Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <iostream>
- #include <string>
- #include <vector>
- #include <algorithm>
- #include <windows.h>
- using namespace std;
- typedef unsigned char uc;
- /*
- Программа работает с кодировкой windows-1251 (ansi)
- Коды русских символов:
- Ё = 168
- ё = 184
- А = 192
- ...
- Я = 223
- а = 224
- ...
- я = 255
- */
- // Функция определяет, является ли русская буква заглавной
- bool isupper_ru(uc c) {
- return c >= 192 && c <= 223 || c == 168;
- }
- // Функция определяет, является ли символ русской буквой
- bool isrus(uc c) {
- return c == 168 || c == 184 || c >= 192 && c <= 255;
- }
- // Функция осуществляет сдвиг ТОЛЬКО русских символов по Цезарю
- // s - изменяемая строка, offset - сдвиг по Цезарю
- // &s - позволит сделать так, чтобы при изменении объекта s в функции, объект s менялся и вне функции
- void crypto(string &s, int offset) {
- for (int i = 0; i < s.size(); ++ i) {
- uc c = (uc)s[i];
- if (isrus(c)) {
- /*
- Ниже происходит преобразование кодов русских символов
- в их порядковый номер в алфавите, затем происходит
- сдвиг по Цезарю и обратное преобразование (из позиции
- в алфавите в код символа). Действия производятся отдельно
- для заглавных и отдельно для строчных букв.
- */
- if (isupper_ru(c)) {
- if (c == 168)
- c = 6;
- else {
- c -= 192;
- if (c >= 6)
- ++ c;
- }
- c = (c + offset) % 33;
- if (c == 6)
- c = 168;
- else {
- if (c >= 7)
- -- c;
- c += 192;
- }
- }
- else {
- if (c == 184)
- c = 6;
- else {
- c -= 224;
- if (c >= 6)
- ++ c;
- }
- c = (c + offset) % 33;
- if (c == 6)
- c = 184;
- else {
- if (c >= 7)
- -- c;
- c += 224;
- }
- }
- s[i] = (char)c; // Замена символа строки на новый
- }
- }
- }
- // Функция возвращает vector из n первых слов словаря данной программы
- vector<string> read_words(const int n) {
- vector<string> ret(0);
- char buf[128];
- FILE* f = fopen("words.num", "r");
- for (int i = 0; i < n; ++ i) {
- fscanf(f, "%*s%*s%s", buf);
- ret.push_back(string(buf));
- }
- fclose(f);
- return ret;
- }
- // Функция преобразует любой русский символ в строчной и возвращает преобразованный символ
- // Если символ строчной, функция не преобразует его.
- uc tolower_ru(uc code) {
- if (isupper_ru(code)) {
- if (code == 168)
- code = 184;
- else
- code += 32;
- return code;
- }
- else
- return code;
- }
- // Возвращает строку в нижнем регистре
- string stolower_ru(const string s) {
- string ret;
- for (int i = 0; i < s.size(); ++ i) {
- ret.push_back(tolower_ru(s[i]));
- }
- return ret;
- }
- const int _n = 69307; // Количество слов в файле со словами
- //69307
- int main(void) {
- SetConsoleCP(1251); // Устанавливает кодировку потока ввода
- SetConsoleOutputCP(1251); // Устанавливает кодировку потока вывода
- vector<string> words = read_words(_n);
- char buf[16384];
- scanf("%[^\n]", buf); // Ввод происходит до перевода строки (enter)
- string s = buf;
- vector<string> strs(33); // Массив для сохранения преобразованных по Цезарю строк
- vector<int> cnts(33); // Массив для сохранения количества соответствий для строк массива strs с соответствующими индексами
- // Перебор каждого смещения
- for (int i = 0; i < 33; ++ i) {
- strs[i] = s;
- cnts[i] = 0;
- uc c;
- string word; // Здесь будут храниться русские слова
- // Ниже перебор каждого символа строки
- for (int j = 0; j < s.size(); ++ j) {
- c = (uc)s[j];
- if (isrus(c))
- // Если символ является русской буквой
- word.push_back(c);
- if (!isrus(c) && !word.empty() || j == s.size() - 1) {
- /*
- Если символ не является русской буквой
- и при этом строка не пуста (значит, что русское
- слово закончилось и его надо сравнить со словами
- словаря данной программы).
- */
- if (!word.empty())
- // Сравнение
- if (count(words.begin(), words.end(), stolower_ru(word)))
- ++ cnts[i]; // +1 к числу соответствий всей строки, если слово найдено в словаре данной программы
- word.clear(); // Отчистка для записи следующего слова
- }
- }
- if (i != 32)
- crypto(s, 1); // Русские буквы строки s смещаются ещё на одну позицию, если в этом есть смысл ...
- // ... (Если это не последняя итерация цикла)
- }
- int index = max_element(cnts.begin(), cnts.end()) - cnts.begin();
- // Выше поиск максимального числа соответствий и получения индекса элемента в массиве cnts
- cout << "\n" << strs[index] << "\n";
- cout << "Число совпадений: " << cnts[index] << "\n";
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement