Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
24
Добавлен:
19.05.2015
Размер:
719.36 Кб
Скачать

Var I, count1, count2, sumFf: integer;

s1, s2: string;

k: char;

begin

readln(s1);

readln(s2);

sumFF := 0;

for k:='A' to 'Z' do begin

count1 := 0;

for i:=1 to length(s1) do

if k = UpCase(s1[i]) then

count1 := count1 + 1;

count2 := 0;

for i:=1 to length(s2) do

if k = UpCase(s2[i]) then

count2 := count2 + 1;

sumFF := sumFF + count1 * count2;

end;

if length(s1)*length(s2) > 0 then

writeln(sumFF/(length(s1)*length(s2)):10:3)

else

writeln(0);

end.

Проанализируем эффективность. Прежде всего, мы избавились от массивов (это хорошо)! Но количество операций стали пропорционально 26*(length(s1)+length(s2)), поскольку получился вложенный цикл. Это значит, что скорость вычислений уменьшилась (стало хуже!), а эффективность по памяти – увеличилась (стало лучше!).

Ещё один вариант, который не использует массивов и быстро работает для коротких строк. Фактически нас интересуют только те символы, которые встречаются в обеих строках, поэтому можно в цикле рассматривать все символы одной строки, например, s1:

sumFF := 0;

for i:=1 to length(s1) do begin

{ если s[i] – латинская буква то

подсчитать count1 – сколько раз она входит в s1

подсчитать count2 – сколько раз она входит в s2

sumFF := sumFF + count1 * count2;

все }

end;

Здесь есть только одна проблема – а что если в первой строке буквы повторяются? Чтобы ее решить, можно «забивать» уже рассмотренные буквы пробелами, например, так (для упрощения считаем, что в языке есть функция UpCase):

for i:=1 to Length(s1) do begin

k := UpCase(s1[i]);

if ('A' <= k) and (k <= 'Z') then begin

{ считаем эти буквы в оставшейся части строки s1 }

count1 := 1;

for j:=i+1 to Length(s1) do

if k = UpCase(s1[j]) then begin

count1 := count1 + 1;

s1[j] := ' '; { забиваем букву пробелом }

end;

{ считаем эти буквы в строке s2 }

count2 := 0;

for j:=1 to Length(s2) do

if k = UpCase(s2[j]) then

count2 := count2 + 1;

{ увеличиваем сумму }

sumFF := sumFF + count1 * count2;

end;

Теперь остается только вывести результат на экран. Вот полная программа:

Var I, j, count1, count2, sumFf: integer;

s1, s2: string;

k: char;

begin

readln(s1);

readln(s2);

sumFF := 0;

for i:=1 to length(s1) do begin

k := UpCase(s1[i]);

if ('A' <= k) and (k <= 'Z') then begin

count1 := 1;

for j:=i+1 to Length(s1) do

if k = UpCase(s1[j]) then begin

count1 := count1 + 1;

s1[j] := ' ';

end;

count2 := 0;

for j:=1 to Length(s2) do

if k = UpCase(s2[j]) then

count2 := count2 + 1;

writeln(k, ' ', count1, ' ', count2);

sumFF := sumFF + count1 * count2;

end;

end;

if length(s1)*length(s2) > 0 then

writeln(sumFF/(length(s1)*length(s2)):10:3)

else

writeln(0);

end.

Проанализируем эффективность. Количество операций стало пропорционально произведению длин строк (получился вложенный цикл), его можно оценить как C*length(s1)*length(s2). Для длинных строк произведение длин во много раз больше, чем сумма длин, поэтому программа будет работать медленнее, чем предыдущий вариант. А для коротких строк – быстрее.

  1. В этой задаче сначала нужно заполнить массив слов (обучающий блок). Естественно объявить массив так:

Соседние файлы в папке ЕГЗ_2012_Поляков_май