e-olymp 2164. Шифр Юлия

Задача. Юлий Цезарь использовал свой способ шифрования текста. Каждая буква заменялась на следующую по алфавиту через [latex]k[/latex] позиций по кругу. Необходимо по заданной шифровке определить исходный текст.

Входные данные: В первой строке дана шифровка, состоящая из не более чем 255 заглавных латинских букв. Во второй строке число [latex]k (1[/latex] [latex]\leq[/latex] [latex]k[/latex] [latex]\leq[/latex] [latex]10)[/latex].

Выходные данные: Требуется вывести результат расшифровки.

Тесты:

Входные данные Выходные данные
1 XPSE

1

WORD
2 ZABC

3

WXYZ

Код программы:

Алгоритм решения:

Каждая буква строки является элементом массива [latex]cipher[/latex]. Чтобы расшифровать строку нужно от значения [latex]i[/latex]-го элемента массива отнять [latex]k[/latex], тем самым сдвинуть символ на [latex]k[/latex] единиц по алфавиту, и заменить первоначальный символ на полученный результат. В случае если разница символа [latex]i[/latex]-го элемента и числа [latex]k[/latex] не входит в множество заглавных латинских букв, требуется от символа «Z» отнять оставшееся кол-во шагов [latex]k[/latex] (то есть не считая те которые уже были пройдены от изначального символа символа до крайнего символа «A»), и заменить первоначальный символ на полученный результат. Можно не беспокоиться о том, что символ вернется к «Z» более чем один раз так как условие исключает этот вариант ([latex]k<=10[/latex] при 26-ти символах латинского алфавита).

Используя цикл, повторяющийся столько же, сколько символов в строке [latex]cipher[/latex], требуется применить описанный алгоритм к каждому элементу массива. По окончанию работы цикл, вывести строку cipher, содержащую уже расшифрованные символы.

Код программы с типом данных  string:

Алгоритм решения:

Чтобы расшифровать слово, находящееся в строке [latex]cipher[/latex], необходимо заменить каждую букву данной строки на букву, находящуюся на [latex](find — k)[/latex] позиции строки [latex]alp[/latex], где [latex]alp[/latex] — строка, содержащая латинский алфавит, а [latex]find[/latex] — позиция заменяемой буквы в алфавите. В случае если разница [latex]find[/latex] и [latex]k[/latex] меньше нуля, заменяем букву строки [latex]cipher[/latex] на букву, находящуюся на [latex](26 — (k — find))[/latex] позиции строки [latex]alp[/latex], то-есть не считая то количество позиций которые уже были пройдены от изначального символа символа до первого символа строки [latex]alp[/latex]. Можно не беспокоиться о том, что символ вернется к к концу алфавита более чем один раз так как условие исключает этот вариант ([latex]k<=10[/latex] при 26-ти символах латинского алфавита).

Related Images:

13 thoughts on “e-olymp 2164. Шифр Юлия

  1. Предполагалось, что Вы воспользуетесь операцией остатка от деления на 26, чтобы не выходить за пределы алфавита. Тогда не понадобилось бы проверять условие. Но так тоже неплохо. Основные замечания по языку, которым написана статья.
    — «член массива» — нужно говорить «элемент массива».
    — «от символа i-го члена массива» — нужно говорить «от значения i-го элемента массива».
    — «результат разницы» называется «разность».
    — «вышеперечисленный алгоритм». Перечислять можно то чего много, а алгоритм у Вас один. Как его перечислять? Возможно Вы имели в виду «описанный»?
    — «Ссылка на компилятор». Я уже как-то объяснял, что ideone.com не компилятор. Там есть возможность выбора компиляторов, но ideone.com расшифровывается как Integrated Development Environment (среда разработки).

    Кстати, историки утверждают, что на самом деле Цезарь всегда использовал k=3. Т.е. это было не шифрование (не было ключа), а кодирование. Просто его кодировочная таблица отличалась на 3 от общепринятой в то время.

  2. — Замените, пожалуйста, это find - k > 26?cipher.at(i) = alp.at(26 - (k - find)):cipher.at(i) = alp.at(find-k); на условный оператор. Т.е. такой трюк, конечно, сработает, но для каждого инструмента своё назначение.
    — Это size_t find = alp.find(cipher.at(i)); не самый простой способ узнать номер буквы . Лучше использовать find = cipher[i] - 'A' сделает тоже самое, но мгновенно. В условиях данной задачи, конечно.

    • Исправил оба пункта, однако не совсем понимаю чем именно условный оператор лучше тернарного в данной ситуации. Строка кода не кажется слишком длинной.

    • Тернарная операция имеет результат. Результат операции следовало бы как-то использовать. В тех случаях когда, в обоих ветках условного оператора генерируется какое-то значение, будет работать и тернарная операция. Если результат её работы игнорировать. Но не для этого она предназначена.
      Общее правило такое. Условный оператор нужно использовать когда нужно в зависимости от некоторого условия выполнять различные действия. Тернарная операция нужна при вычислениях значения, которых зависит от некоторого условия. Т.е. если результат вычислений Вам не нужен, то не нужна и тернарная операция.
      В данном конкретном случае тернарная операция подходит, но в другом формате cipher[i] = ...? ... : ...;. Если хотите оставить первый код, пожалуйста откорректируйте соответствующие строчки.

  3. Хорошо.
    Осталось что-то сделать с 11-й строкой первого кода: cipher[i] - k >= 'A'?cipher[i] -= k:cipher[i] = 'Z' - (k - (cipher[i] - '@'));. Я уже объяснял — нужно переделать по схеме cipher[i] = ...? ... : ...;. Просто замените многоточия на необходимый код.
    И, конечно, нужно избавиться от магических чисел 256 и 26 причудливо разбросанных по тексту обоих программ 🙂

    По оформлению.
    Вы пишите: Код программы с типом данных [latex]»string»[/latex]. Зачем оформлять название типа данных в виде математической формулы? Посмотрите, как latex превратил Ваши кавычки во вторую производную. Для красивого оформления фрагментов кода (при желании) можно использовать тег <code>string</code>. Выглядеть это будет так — string.

    • Конечно, магическое. В двух местах программы должно быть одно и тоже значение. Комментариями это не компенсируется. Нужно заводить константу. С 26, Вы тоже не справились, а схитрили. Мы ведь это обсуждали и на лекциях, и на практике. Если появляется константа, для неё должно быть имя. Или через #define ABC_SIZE 26 или через const int ABC_SIZE = 26;

      Вы так и не исправили тернарную операцию. Может Вы не читаете моих замечаний?

Добавить комментарий