Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <iostream>
- #include <locale.h>
- #include <string>
- #include <vector>
- #include <algorithm>
- using namespace std;
- typedef unsigned short int usi;
- typedef unsigned char uc;
- // Функция возвращает код русского символа (в таблице Юникода) записанного в utf-8
- usi getcode(usi c) {
- usi ret = 0, p1 = 0xff00, p2 = 0x00ff;
- uc a = 0x1f, b = 0x3f;
- ret += (((c & p1) >> 8) & a);
- ret <<= 6;
- ret += (c & p2 & b);
- return ret;
- }
- // Функция возвращает преобразованный в utf-8 код русского символа
- usi toutf8(usi c) {
- usi ret = 0;
- uc a = 0xc0, b = 0x80;
- b += c & 0x003f;
- c >>= 6;
- a += c & 0x001f;
- ret += a;
- ret <<= 8;
- ret += b;
- return ret;
- }
- bool isupper_ru(usi c) {
- return c == 0x401 || c >= 0x410 && c <= 0x42f;
- }
- void crypto(string &s, int offset) {
- if (offset < 0)
- offset = 33 + offset;
- unsigned short int a = 0;
- unsigned char b = 0x80;
- for (int i = 0; i < s.size(); ++ i) {
- if (s[i] < 0) {
- usi t = 0, code;
- // Получение кода utf-8
- t += (uc)s[i];
- t <<= 8;
- t += (uc)s[i + 1];
- //
- code = getcode(t);
- /*
- (Ниже) Сдвиг русского символа по шифру Цезаря
- по определённому смещению.
- Отдельное описание для строчных и заглавных букв.
- Код символа для удобства преобразуется
- в порядковый номер буквы в алфавите и в этом виде
- происходит сдвиг.
- */
- if (isupper_ru(code)) {
- if (code >= 0x410)
- code -= 0x410;
- else
- code = 40;
- if (code >= 6 && code <= 31)
- ++ code;
- if (code == 40)
- code = 6;
- code = (code + offset) % 33;
- if (code == 6)
- code = 0x401;
- if (code >= 0 && code <= 33) {
- if (code >= 7)
- -- code;
- code += 0x410;
- }
- }
- else {
- code -= 0x430;
- if (code >= 6 && code <= 32)
- ++ code;
- if (code > 32)
- code = 6;
- code = (code + offset) % 33;
- if (code == 6)
- code = 33;
- if (code >= 7 && code != 33)
- -- code;
- code += 0x430;
- }
- code = toutf8(code);
- s[i] = (char)(code >> 8);
- s[i + 1] = (char)(code & 0x00ff);
- ++ i;
- }
- }
- }
- // Функция возвращает 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;
- }
- usi tolower_ru(usi code) {
- if (isupper_ru(code)) {
- if (code == 0x401)
- code = 0x451;
- else
- code += 0x20;
- }
- return code;
- }
- string stolower_ru(const string s) {
- string ret;
- for (int i = 0; i < s.size(); ++ i) {
- if (s[i] < 0) {
- usi code = (uc)s[i];
- code <<= 8;
- code += (uc)s[i + 1];
- code = toutf8(tolower_ru(getcode(code)));
- ret.push_back((char)(code >> 8));
- ret.push_back((char)(code & 0x00ff));
- ++ i;
- }
- else
- ret.push_back(s[i]);
- }
- return ret;
- }
- const int _n = 69307;
- //69307
- int main(void) {
- setlocale(LC_ALL, "Russian");
- //freopen("input.txt", "r", stdin);
- vector<string> words = read_words(_n);
- char buf[16384];
- scanf("%[!-~А-ПР-Яа-пр-яЁё ]", buf);
- string s = buf;
- vector<string> strs(33);
- vector<int> cnts(33);
- for (int i = 0; i < 33; ++ i) {
- strs[i] = s;
- cnts[i] = 0;
- char c;
- string word;
- for (int j = 0; j < s.size(); ++ j) {
- c = s[j];
- if (c > 0 && !word.empty() || j == s.size() - 1) {
- if (c < 0)
- word.push_back(c);
- if (count(words.begin(), words.end(), stolower_ru(word)))
- ++ cnts[i];
- word.clear();
- }
- else if (c < 0)
- word.push_back(c);
- }
- if (i != 32)
- crypto(s, 1);
- }
- int index = max_element(cnts.begin(), cnts.end()) - cnts.begin();
- cout << strs[index] << "\n";
- cout << "Число совпадений: " << cnts[index] << "\n";
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement