Задача. Юлий Цезарь использовал свой способ шифрования текста. Каждая буква заменялась на следующую по алфавиту через [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 |
Код программы:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#include <iostream> #include <cstring> using namespace std; int main() { const int MAX_SIZE = 256; // 256 - максимальное кол-во букв по условию + нулевой символ char *cipher = new char [MAX_SIZE]; cin.getline (cipher,MAX_SIZE); int k; cin >> k; for(int i = 0; i < strlen(cipher); i++){ // Цикл дешифровки выполняется до последней буквы if(cipher[i] >= 'A' + k) cipher[i] -= k; else cipher[i] = 'Z' - (k - (cipher[i] - '@')); //cipher[i] - '@' расстояние между i-ым символом и символом 'A', где '@' - символ идущий перед символом 'A' /* Если полученный символ принадлежит к заглавным латинским буквам, ставим его на место зашифрованного Если нет, то возвращаемся к символу "Z" и отступаем от него на k минус уже пройденное кол-во символов */ } cout << cipher; return 0; } |
Алгоритм решения:
Каждая буква строки является элементом массива [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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#include <iostream> #include <string> using namespace std; int main() { string cipher; getline(cin,cipher); int k; const int ABC_SIZE = 26; // Количество символов латинского алфавита cin >> k; string alp = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; for(int i = 0; i < cipher.length(); i++){ int find = cipher[i] - 'A'; if(find - k < 0) cipher.at(i) = alp.at(ABC_SIZE - (k - find)); else cipher.at(i) = alp.at(find-k); } cout << cipher; return 0; } |
Алгоритм решения:
Чтобы расшифровать слово, находящееся в строке [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-ти символах латинского алфавита).