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

Var k: char;

f1, f2: array['A'..'Z'] of integer;

Сначала массивы счётчиков нужно обнулить:

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

f1[k] := 0; f2[k] := 0;

end;

Дальше в цикле обрабатываем каждую строку. Например, для строки s1 получаем

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

{ обработать символ s1[i] }

end;

Что входит в обработку? Нужно определить индекс нужного счётчика («номер» символа в латинском алфавите), и затем увеличить этот счётчик (элемент массива). Необходимо учесть две особенности:

  1. все строчные буквы нужно преобразовывать к прописным (заглавным), так как индексы массивов f1 и f2 – заглавные буквы; например, если символьная переменная k содержит строчную букву, для преобразования её в соответствующую прописную нужно вычесть из её кода (полученного с помощью функции Ord) код буквы «a» и прибавить код буквы «A», полученный новый код преобразовать в символ с помощью функции Chr:

k := Chr(Ord(s1[i]) - Ord('a') + Ord('A'));

вместо этого можно просто вызвать функцию UpCase (преобразовать символ в верхний регистр), если она есть в той версии языка, на которой вы пишете:

k := UpCaSe(s1[i]);

  1. все символы, не являющиеся латинскими буквами, нужно игнорировать (счётчики не меняются).

Поэтому цикл обработки строки s1 выглядит так:

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

k := ' ';

if ('A' <= s1[i]) and (s1[i] <= 'Z') then

k := s1[i]

else

if ('a' <= s1[i]) and (s1[i] <= 'z') then

k := Chr(Ord(s1[i]) - Ord('a') + Ord('A'));

if k <> ' ' then f1[k] := f1[k] + 1;

end;

Обратите внимание, что если очередной символ не является латинской буквой (заглавной или строчной), в переменной k остается пробел, и счетчики не изменяются.

Для строки s2 нужно написать аналогичный цикл:

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

k := ' ';

if ('A' <= s2[i]) and (s2[i] <= 'Z') then

k := s2[i]

else

if ('a' <= s2[i]) and (s2[i] <= 'z') then

k := Chr(Ord(s2[i]) - Ord('a') + Ord('A'));

if k <> ' ' then f2[k] := f2[k] + 1;

end;

Теперь находим сумму произведений соответствующих счетчиков:

sumFF := 0;

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

sumFF := sumFF + f1[k]*f2[k];

и выводим ответ:

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

Вот полная программа:

program qq;

Var I, sumFf: integer;

s1, s2: string;

f1, f2: array['A'..'Z'] of integer;

k: char;

begin

readln(s1);

readln(s2);

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

f1[k] := 0; f2[k] := 0;

end;

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

k := ' ';

if ('A' <= s1[i]) and (s1[i] <= 'Z') then

k := s1[i]

else

if ('a' <= s1[i]) and (s1[i] <= 'z') then

k:= Chr(Ord(s1[i]) - Ord('a') + Ord('A'));

{ или k:= UpCase(s1[i]); }

if k <> ' ' then f1[k] := f1[k] + 1;

end;

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

k := ' ';

if ('A' <= s2[i]) and (s2[i] <= 'Z') then

k := s2[i]

else

if ('a' <= s2[i]) and (s2[i] <= 'z') then

k := Chr(Ord(s2[i]) - Ord('a') + Ord('A'));

{ или k:= UpCase(s2[i]); }

if k <> ' ' then f2[k] := f2[k] + 1;

end;

sumFF := 0;

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

sumFF := sumFF + f1[k]*f2[k];

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

end.

Заметим, что обе строки должны содержать хотя бы по одному символу. Если этот не гарантируется, оператор вывода нужно записать так:

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

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

else

writeln(0);

В качестве оптимизации можно заранее вычислить длины обеих строк и записать их в новые переменные.

Однако, не все так просто. Является ли эта программа эффективной? С одной стороны, количество операций линейно зависит от длин строк s1 и s2 (это хорошо!), его можно оценить как C*(length(s1)+length(s2))при некоторой постоянной C. С другой стороны, мы использовали два массива по 26 элементов в каждом (можно придраться к неэффективности по использованию памяти).

Итак, попробуем без массивов. Можно, например, сделать цикл по всем буквам латинского алфавита и считать, сколько раз входит каждая буква в первую и вторую строки (эти переменные-счётчики назовем count1 и count2). После прохода по обеим строкам, добавляем произведение count1*count2 к сумме (для упрощения считаем, что в языке есть функция UpCase):

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;

Вот полная программа:

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