Размер шрифта: A AA Изображения Выключить Включить Цвет сайта Ц Ц Ц Х
Бесплатный конструктор сайтовuCoz
Пятница, 25.07.2025, 15:40
Приветствую Вас Гость | RSS

Сайт учителя информатики  и ИКТ Шинкаренко Евгения Александровича

Реклама
Оцените сайт
Оцените мой сайт
Всего ответов: 837
Программирование
Какой язык программирования выбрать для подготовки к ЕГЭ
Всего ответов: 804

Решение задачи №5.

Задача №5.
На вход программы подается текст заклинания, состоящего не более чем из 200 символов, заканчивающийся точкой (символ «точка» во входных данных единственный). Оно было зашифровано Гарри Поттером следующим образом. Сначала Гарри определил количество букв в самом длинном слове, обозначив полученное число K (словом называется непрерывная последовательность английских букв, слова друг от друга отделяются любыми другими символами, длина слова не превышает 20 символов). Затем он заменил каждую английскую букву в заклинании на букву, стоящую в алфавите на К букв ранее (алфавит считается циклическим, то есть перед буквой А стоит буква Z), оставив другие символы неизменными. Строчные буквы при этом остались строчными, а прописные - прописными. Требуется написать как можно более эффективную программу (укажите используемую версию языка программирования, например, Borland Pascal 7.0), которая будет выводить на экран текст расшифрованного заклинания. Например, если зашифрованный текст был таким:
Zb Ra Ca,Dab Ra.
то результат расшифровки должен быть следующим:
Се Ud Fd,Gde Ud.

Решение задачи №5.

var
st:char;    {символьная переменная будет считывать посимвольно текст заклинания}
sl:string[200];  {строковая переменная будет принимать значение всего текста заклинания}
k,max,i,n,x:integer; {k-счетчик символов для определения самого длинного слова,max-самое длинное слово, i-индекс,n-количество символов во всем заклинании}
begin
k:=0;   {обнуляем начальные значение переменных k, max,n}
max:=0;
n:=0;
repeat  {открываем цикл для считывания символов заклинания}
begin
read(st);  {символьная переменная st считывает символ}
sl:=sl+st;  {строковая переменная  увеличивает свое значение на считанный символ}
n:=n+1;
if ((ord(st)>64) and (ord(st)<91))or ((ord(st)>96)and(ord(st)<123)) then {определяем является ли считанный символ английской буквой, ниже подробнее разберем данный фрагмент}
k:=k+1  {если символ - буква, то переменная k увеличивает значение на единицу}
else
if k>max then  {в противном случае, сравниваем переменную k с переменной max, если k больше, то...}
begin
max:=k;  {...то переменная max принимает значение переменной k}
k:=0;   {а переменная k обнуляется}
end
else
k:=0;   {в противном случае k  просто обнуляется}
end;
until st='.';  {если следующий символ точка, цикл закрывается, в цикле мы считали все заклинание в строковую переменную sl, подсчитали количество всех символов в заклинании (переменная n) и узнали количество букв в самом длинном слове (переменная - max)}
for i:=1 to n do {задаем цикл с 1 до n, для изменения
английской букву в заклинании на букву, стоящую в алфавите на max букв далее}
if ((ord(sl[i])>64) and (ord(sl[i])<91))or ((ord(sl[i])>96)and(ord(sl[i])<123)) then {определяем является ли считанный символ английской буквой, если символ - буква то...}
if (ord(sl[i])>64) and (ord(sl[i])<91) then {... проверяем прописная ли эта буква, если да то....}
if (ord(sl[i])+max)<91 then sl[i]:=char(ord(sl[i])+max) {проверяем будет ли символ прописной буквой после увеличения его кода на величину переменной max, если да, то код символа увеличивается на величину max, символ изменяется}
else
begin {в противном случае, так как алфавит цикличный, необходимо определить насколько символ сдвинется относительно начала алфавита   ...}
x:=max-(90-ord(sl[i]));  {определяем на сколько увеличится код символа относительно кода символа "A"}
sl[i]:=char(64+x); {увеличиваем код символа на значение переменной x}
end
else {если буква английского алфавита строчная, то....}
if (ord(sl[i])+max)<123 then sl[i]:=char(ord(sl[i])+max) {
проверяем будет ли символ строчной буквой после увеличения его кода на величину переменной max, если да, то код символа увеличивается на величину max, символ изменяется}
else
begin
{в противном случае, так как алфавит цикличный, необходимо определить насколько символ сдвинется относительно начала алфавита   ...}
x:=max-(122-ord(sl[i])); {определяем на сколько увеличится код символа относительно кода символа "a"}
sl[i]:=char(96+x); {увеличиваем код символа на значение переменной x}
end; {после прохода цикла символы алфавита передвинулись на max букв далее, а остальные символы не изменились, мы раскодировали заклинание}
writeln(sl);  {вывели на экран результат}
end.

Чтобы расшифровать текст заклинания, нам надо поменять английские буквы на буквы, стоящие в алфавите на K букв ВПЕРЕД (где К -количество букв в самом длинном слове (по задаче это переменная max)).

Алгоритм решения задачи
  • посимвольно считываем все символы введенные с клавиатуры до точки, считаем количество символов, определяем сколько букв в самом большом слове, всю фразу записываем в строковую переменную 
  • далее задаем цикл для смещения символов
  • в цикле проверяем является ли символ буквой, затем проверяем прописная ли буква или строчная
  • сдвигаем буквы на величину количества букв в самом большом слове, для этого изменяем величину кода символа (ниже представлена таблица кодов символов)
  • после окончание цикла все буквы изменили свои значения, а другие символы остались неизменными
Таблица кодов ASCII

Разберем следующие строки
if ((ord(sl[i])>64) and (ord(sl[i])<91))or ((ord(sl[i])>96)and(ord(sl[i])<123)) then
в данной строке идет сравнение кода символа (ord(sl[i]), функция ord возвращает номер кода символа из таблицы приведенной выше) с интервалами от 65 до 90 (прописные буквы, см. таблицу выше) и от 97 до 122 (строчные буквы, см. таблицу выше).

if (ord(sl[i])+max)<91 then sl[i]:=char(ord(sl[i])+max)
в данной строке идет проверка ((ord(sl[i])+max)<91) - при добавлении к коду символа переменной max остался ли символ ПРОПИСНОЙ буквой (диапазон символов от 65 до 90), если остался то к коду символа прибавляем значение переменной max (ord(sl[i])+max), а получившееся значение обратно переводим в символ (функция char преобразует целое число в символ согласно таблицы кодов, см. выше), в итоге символ меняет свое значение sl[i]:=char(ord(sl[i])+max). Аналогичная ситуация для строки if (ord(sl[i])+max)<123 then sl[i]:=char(ord(sl[i])+max) только проверяем является ли символ строчной буквой (диапазон символов от 97 до 122).

x:=max-(90-ord(sl[i])); 
sl[i]:=char(64+x);

в случае если не выполняется условие указанной выше проверки, то величина символа после к прибавлению к ее коду переменной max выходит из диапазона ПРОПИСНЫХ букв, но по условию задачи у нас алфавит цикличен и после "A" идет "Z", поэтому если код символа превысил 90, то нам необходимо узнать насколько превысил.
Для этого в задаче прописали переменную X, строка 
x:=max-(90-ord(sl[i])); позволяет это сделать, в ней мы от переменной max (на значение которой мы хотим сдвинуть букву вперед) отнимаем следующее значение (90-ord(sl[i]));, где 90-это код символа "Z"(см. таблицу), а ord(sl[i]) - код текущего символа.
Далее прибавляем получившееся значение X к коду символа "A" - 64 (
sl[i]:=char(64+x);), в итоге символ меняет свое значение. Аналогично действуем со строчными буквами.

В итоге строковая переменная примет нужное нам значение, мы расшифровали заклинание.
Возврат к списку задач.
Реклама
Календарь
«  Июль 2025  »
ПнВтСрЧтПтСбВс
 123456
78910111213
14151617181920
21222324252627
28293031
Поиск
Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0
Счетчик яндекс
Яндекс.Метрика