StoneHaos

cezar2

Dec 7th, 2019
180
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <stdio.h>
  2. #include <iostream>
  3. #include <locale.h>
  4. #include <string>
  5. #include <vector>
  6. #include <algorithm>
  7. using namespace std;
  8.  
  9. typedef unsigned short int usi;
  10. typedef unsigned char uc;
  11.  
  12. // Функция возвращает код русского символа (в таблице Юникода) записанного в utf-8
  13. usi getcode(usi c) {
  14.     usi ret = 0, p1 = 0xff00, p2 = 0x00ff;
  15.     uc a = 0x1f, b = 0x3f;
  16.     ret += (((c & p1) >> 8) & a);
  17.     ret <<= 6;
  18.     ret += (c & p2 & b);
  19.     return ret;
  20. }
  21.  
  22. // Функция возвращает преобразованный в utf-8 код русского символа
  23. usi toutf8(usi c) {
  24.     usi ret = 0;
  25.     uc a = 0xc0, b = 0x80;
  26.     b += c & 0x003f;
  27.     c >>= 6;
  28.     a += c & 0x001f;
  29.     ret += a;
  30.     ret <<= 8;
  31.     ret += b;
  32.     return ret;
  33. }
  34.  
  35. bool isupper_ru(usi c) {
  36.     return c == 0x401 || c >= 0x410 && c <= 0x42f;
  37. }
  38.  
  39. void crypto(string &s, int offset) {
  40.     if (offset < 0)
  41.         offset = 33 + offset;
  42.     unsigned short int a = 0;
  43.     unsigned char b = 0x80;
  44.     for (int i = 0; i < s.size(); ++ i) {
  45.         if (s[i] < 0) {
  46.             usi t = 0, code;
  47.             // Получение кода utf-8
  48.             t += (uc)s[i];
  49.             t <<= 8;
  50.             t += (uc)s[i + 1];
  51.             //
  52.             code = getcode(t);
  53.             /*
  54.                 (Ниже) Сдвиг русского символа по шифру Цезаря
  55.                 по определённому смещению.
  56.                 Отдельное описание для строчных и заглавных букв.
  57.                 Код символа для удобства преобразуется
  58.                 в порядковый номер буквы в алфавите и в этом виде
  59.                 происходит сдвиг.
  60.             */
  61.             if (isupper_ru(code)) {
  62.                 if (code >= 0x410)
  63.                     code -= 0x410;
  64.                 else
  65.                     code = 40;
  66.                 if (code >= 6 && code <= 31)
  67.                     ++ code;
  68.                 if (code == 40)
  69.                     code = 6;
  70.                 code = (code + offset) % 33;
  71.                 if (code == 6)
  72.                     code = 0x401;
  73.                 if (code >= 0 && code <= 33) {
  74.                     if (code >= 7)
  75.                         -- code;
  76.                     code += 0x410;
  77.                 }
  78.             }
  79.             else {
  80.                 code -= 0x430;
  81.                 if (code >= 6 && code <= 32)
  82.                     ++ code;
  83.                 if (code > 32)
  84.                     code = 6;
  85.                 code = (code + offset) % 33;
  86.                 if (code == 6)
  87.                     code = 33;
  88.                 if (code >= 7 && code != 33)
  89.                     -- code;
  90.                 code += 0x430;
  91.             }
  92.             code = toutf8(code);
  93.             s[i] = (char)(code >> 8);
  94.             s[i + 1] = (char)(code & 0x00ff);
  95.             ++ i;
  96.         }
  97.     }
  98. }
  99.  
  100. // Функция возвращает vector из n первых слов словаря данной программы
  101. vector<string> read_words(const int n) {
  102.     vector<string> ret(0);
  103.     char buf[128];
  104.     FILE* f = fopen("words.num", "r");
  105.     for (int i = 0; i < n; ++ i) {
  106.         fscanf(f, "%*s%*s%s", buf);
  107.         ret.push_back(string(buf));
  108.     }
  109.     fclose(f);
  110.     return ret;
  111. }
  112.  
  113. usi tolower_ru(usi code) {
  114.     if (isupper_ru(code)) {
  115.         if (code == 0x401)
  116.             code = 0x451;
  117.         else
  118.             code += 0x20;
  119.     }
  120.     return code;
  121. }
  122.  
  123. string stolower_ru(const string s) {
  124.     string ret;
  125.     for (int i = 0; i < s.size(); ++ i) {
  126.         if (s[i] < 0) {
  127.             usi code = (uc)s[i];
  128.             code <<= 8;
  129.             code += (uc)s[i + 1];
  130.             code = toutf8(tolower_ru(getcode(code)));
  131.             ret.push_back((char)(code >> 8));
  132.             ret.push_back((char)(code & 0x00ff));
  133.             ++ i;
  134.         }
  135.         else
  136.             ret.push_back(s[i]);
  137.     }
  138.     return ret;
  139. }
  140.  
  141. const int _n = 69307;
  142. //69307
  143.  
  144. int main(void) {
  145.     setlocale(LC_ALL, "Russian");
  146.     //freopen("input.txt", "r", stdin);
  147.     vector<string> words = read_words(_n);
  148.     char buf[16384];
  149.     scanf("%[!-~А-ПР-Яа-пр-яЁё ]", buf);
  150.     string s = buf;
  151.     vector<string> strs(33);
  152.     vector<int> cnts(33);
  153.     for (int i = 0; i < 33; ++ i) {
  154.         strs[i] = s;
  155.         cnts[i] = 0;
  156.         char c;
  157.         string word;
  158.         for (int j = 0; j < s.size(); ++ j) {
  159.             c = s[j];
  160.             if (c > 0 && !word.empty() || j == s.size() - 1) {
  161.                 if (c < 0)
  162.                     word.push_back(c);
  163.                 if (count(words.begin(), words.end(), stolower_ru(word)))
  164.                     ++ cnts[i];
  165.                 word.clear();
  166.             }
  167.             else if (c < 0)
  168.                 word.push_back(c);
  169.         }
  170.         if (i != 32)
  171.             crypto(s, 1);
  172.     }
  173.     int index = max_element(cnts.begin(), cnts.end()) - cnts.begin();
  174.     cout << strs[index] << "\n";
  175.     cout << "Число совпадений: " << cnts[index] << "\n";
  176.     return 0;
  177. }
RAW Paste Data