Advertisement
leo11

Untitled

Dec 27th, 2020
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 20.23 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <wchar.h>
  4. #include <wctype.h>
  5. #include <locale.h>
  6. #include <string.h>
  7.  
  8. //-------------------------------------------------------------------------------------------------
  9. //Структуры и функции связанные с предложениями
  10.  
  11.  
  12. typedef struct Sentence {
  13.     size_t size;
  14.     size_t capacity;
  15.     wchar_t* sentence;
  16. } Sentence;
  17.  
  18. Sentence* createSentence() {
  19.     Sentence* s = (Sentence*)malloc(sizeof(Sentence));
  20.     if (!s) {
  21.         fprintf(stderr, "Can\'t allocate memory!\n");
  22.         return NULL;
  23.     }
  24.     s->capacity = 0;
  25.     s->size = 0;
  26.     s->sentence = NULL;
  27.     return s;
  28. }
  29.  
  30. void deleteSentence(Sentence** ps) {
  31.     if (*ps) {
  32.         if ((*ps)->sentence) {
  33.             free((*ps)->sentence);
  34.         }
  35.         free(*ps);
  36.         *ps = NULL;
  37.     }
  38. }
  39.  
  40.  
  41. //-------------------------------------------------------------------------------------------------
  42. //Структура и функции связанные с Текстом
  43.  
  44. typedef struct Text {
  45.     size_t size;
  46.     size_t capacity;
  47.     Sentence** text;
  48. } Text;
  49.  
  50.  
  51. Text* createText() {
  52.     Text* t = (Text*)malloc(sizeof(Text));
  53.     if (!t) {
  54.         fprintf(stderr, "Can\'t allocate memory!\n");
  55.         return NULL;
  56.     }
  57.     t->capacity = 0;
  58.     t->size = 0;
  59.     t->text = NULL;
  60.     return t;
  61. }
  62.  
  63. void deleteText(Text** ptext) {
  64.     if (*ptext) {
  65.         if ((*ptext)->text) {
  66.             for (size_t i = 0; i < (*ptext)->size; ++i) {
  67.                 deleteSentence(&(*ptext)->text[i]);
  68.             }
  69.             free((*ptext)->text);
  70.         }
  71.         free(*ptext);
  72.         *ptext = NULL;
  73.     }
  74. }
  75.  
  76.  
  77. //-------------------------------------------------------------------------------------------------
  78. //Функции связанные с созданием предложений
  79.  
  80. wchar_t* addOneSymbol(Sentence* ps, wchar_t symbol) {
  81.     if (!ps) {
  82.         fprintf(stderr, "Poor sentence!\n");
  83.         return NULL;
  84.     }
  85.     if (!ps->sentence) {
  86.         ps->sentence = (wchar_t*)malloc(sizeof(wchar_t) * 2);
  87.         if (!ps->sentence) {
  88.             fprintf(stderr, "Can\'t allocate memory!\n");
  89.             deleteSentence(&ps);
  90.             return NULL;
  91.         }
  92.         (ps->sentence)[0] = symbol;
  93.         (ps->sentence)[1] = L'\0';
  94.         ps->size = 2;
  95.         ps->capacity = 2;
  96.         return ps->sentence;
  97.     }
  98.     if (ps->size + 1 <= ps->capacity) {
  99.         (ps->sentence)[ps->size - 1] = symbol;
  100.         (ps->sentence)[ps->size] = L'\0';
  101.         ++ps->size;
  102.         return ps->sentence;
  103.     }
  104.     wchar_t* t = (wchar_t*)malloc(sizeof(wchar_t) * 2 * ps->capacity);
  105.     if (!t) {
  106.         fprintf(stderr, "Can\'t allocate memory!\n");
  107.         deleteSentence(&ps);
  108.         return NULL;
  109.     }
  110.     ps->capacity *= 2;
  111.     wcscpy(t, ps->sentence);
  112.     free(ps->sentence);
  113.     t[ps->size - 1] = symbol;
  114.     t[ps->size] = L'\0';
  115.     ++ps->size;
  116.     ps->sentence = t;
  117.     return ps->sentence;
  118. }
  119.  
  120. Sentence* readOneSentence(int* weof) {
  121.     Sentence* s = createSentence();
  122.     wchar_t symbol;
  123.     while (!((symbol = fgetwc(stdin)) == L'.')) {
  124.         if (!addOneSymbol(s, symbol)) {
  125.             deleteSentence(&s);
  126.             return NULL;
  127.         }
  128.     }
  129.     if (!addOneSymbol(s, symbol)) {
  130.         deleteSentence(&s);
  131.         return NULL;
  132.     }
  133.     symbol = fgetwc(stdin);
  134.     if (symbol == L'\n') {
  135.         *weof = 1;
  136.     }
  137.     return s;
  138. }
  139.  
  140.  
  141. Sentence* addOneSentence(Text* ptext, Sentence* s) {
  142.     if (!ptext) {
  143.         fprintf(stderr, "Poor text!\n");
  144.         return NULL;
  145.     }
  146.     if (!ptext->text) {
  147.         ptext->text = (Sentence**)malloc(sizeof(Sentence*) * 2);
  148.         if (!ptext->text) {
  149.             fprintf(stderr, "Can\'t allocate memory!\n");
  150.             deleteText(&ptext);
  151.             return NULL;
  152.         }
  153.         (ptext->text)[0] = s;
  154.         ptext->size = 1;
  155.         ptext->capacity = 2;
  156.         return s;
  157.     }
  158.     if (ptext->size + 1 <= ptext->capacity) {
  159.         (ptext->text)[ptext->size] = s;
  160.         ++ptext->size;
  161.         return s;
  162.     }
  163.     Sentence** t = (Sentence**)malloc(sizeof(Sentence*) * 2 * ptext->capacity);
  164.     if (!t) {
  165.         fprintf(stderr, "Can\'t allocate memory!\n");
  166.         deleteText(&ptext);
  167.         return NULL;
  168.     }
  169.     ptext->capacity *= 2;
  170.     memcpy(t, ptext->text, sizeof(Sentence*) * ptext->size);
  171.     free(ptext->text);
  172.     t[ptext->size] = s;
  173.     ++ptext->size;
  174.     ptext->text = t;
  175.     return s;
  176. }
  177.  
  178.  
  179. //-------------------------------------------------------------------------------------------------
  180. //Печать текста на экран
  181.  
  182. void printText(Text* t) {
  183.     for (size_t i = 0; i < t->size; ++i) {
  184.         wprintf(L"%ls\n", t->text[i]->sentence);
  185.     }
  186.     wprintf(L"\n");
  187. }
  188.  
  189.  
  190. //-------------------------------------------------------------------------------------------------
  191.  
  192.  
  193. wint_t myWCmp(const wchar_t* a, const wchar_t* b)
  194. {
  195.     while (*a && *b && towlower(*a) == towlower(*b)) { ++a; ++b; }
  196.     return towlower(*a) - towlower(*b);
  197. }
  198.  
  199. //Полный текст уже после удаления одинаковых предложений
  200. Text* getFullSentencesText() {
  201.     Sentence* s = NULL;
  202.     Text* t = NULL;
  203.     t = createText();
  204.     int weof = 0;
  205.     while (!weof) {
  206.         s = readOneSentence(&weof);
  207.         int n = 1;
  208.         for (size_t i = 0; i < t->size; ++i) {
  209.             if (myWCmp(s->sentence, t->text[i]->sentence) == 0) {
  210.                 n = 0;
  211.                 deleteSentence(&s);
  212.                 break;
  213.             }
  214.         }
  215.         if (n == 1) {
  216.             addOneSentence(t, s);
  217.         }
  218.     }
  219.     return t;
  220. }
  221.  
  222.  
  223. //-------------------------------------------------------------------------------------------------
  224. //Первая функция: Анаграмма
  225.  
  226. int isEnglishLetter(wchar_t symbol) {                                                       //Проверка: является ли символ буквой из латинского алфавита
  227.     return (symbol >= L'a') && (symbol <= L'z');
  228. }
  229.  
  230. int isRussianLetter(wchar_t symbol) {                                                       //Проверка: является ли символ буквой кириллического алфавита
  231.     return (symbol >= L'а') && (symbol <= L'я');
  232. }
  233.  
  234. int isNumberLetter(wchar_t symbol) {                                                        //Проверка: является ли символ цифрой
  235.     return (symbol >= L'0') && (symbol <= L'9');
  236. }
  237.  
  238. int isOkSymbolForAnagramm(wchar_t symbol) {                                                 //Проверка символа на латиницу/кириллицу/цифру
  239.     return isEnglishLetter(symbol) || isRussianLetter(symbol) || isNumberLetter(symbol);
  240. }
  241.  
  242. void setAlphabet(Sentence* s, size_t* english, size_t* russian, size_t* numbers) {          //Функция считает сколько букв каждого алфавита каждого языка или цифр
  243.     for (size_t i = 0; i < 26; ++i) {
  244.         english[i] = 0;
  245.     }
  246.     for (size_t i = 0; i < 33; ++i) {
  247.         russian[i] = 0;
  248.     }
  249.     for (size_t i = 0; i < 10; ++i) {
  250.         numbers[i] = 0;
  251.     }
  252.     wchar_t* p = s->sentence;
  253.     while (*p != L'\0') {
  254.         wchar_t symbol = towlower(*p);
  255.         if (isOkSymbolForAnagramm(symbol)) {
  256.             if (isEnglishLetter(symbol)) {              //В массиве счетчик букв каждого алфавита по порядку
  257.                 ++english[symbol - L'a'];
  258.             }
  259.             else if (isRussianLetter(symbol)) {
  260.                 ++russian[symbol - L'а'];
  261.             }
  262.             else {
  263.                 ++numbers[symbol - L'0'];
  264.             }
  265.         }
  266.         ++p;
  267.     }
  268. }
  269.  
  270. int isAnagramm(size_t* english1, size_t* russian1, size_t* numbers1, size_t* english2, size_t* russian2, size_t* numbers2) {
  271.     for (size_t i = 0; i < 26; ++i) {
  272.         if (english1[i] != english2[i]) {                                           //Функция проверки массивов, содержащих флаги кол-ва букв каждого алфавита
  273.             return 0;                                                               //на равность
  274.         }
  275.     }
  276.     for (size_t i = 0; i < 33; ++i) {
  277.         if (russian1[i] != russian2[i]) {
  278.             return 0;
  279.         }
  280.     }
  281.     for (size_t i = 0; i < 10; ++i) {
  282.         if (numbers1[i] != numbers2[i]) {
  283.             return 0;
  284.         }
  285.     }
  286.     return 1;
  287. }
  288.  
  289.  
  290.  
  291. void printAnagramms(Text* t) {                                                              //Функция, печатающая на экран предложения-анаграммы
  292.     size_t english1[26];
  293.     size_t russian1[33];
  294.     size_t numbers1[10];
  295.  
  296.     size_t english2[26];
  297.     size_t russian2[33];
  298.     size_t numbers2[10];
  299.  
  300.     int* flags = (int*)malloc(sizeof(int) * t->size);
  301.     for (size_t i = 0; i < t->size; ++i) {
  302.         flags[i] = 1;
  303.     }
  304.     int counter1 = 0;
  305.     for (size_t i = 0; i < t->size; flags[i] = 0, ++i) {
  306.         int counter2 = 0;
  307.         if (flags[i]) {
  308.             setAlphabet(t->text[i], english1, russian1, numbers1);
  309.             int first = 1;
  310.             for (size_t j = i + 1; j < t->size; ++j) {
  311.                 if (flags[i]) {
  312.                     setAlphabet(t->text[j], english2, russian2, numbers2);
  313.                     if (isAnagramm(english1, russian1, numbers1, english2, russian2, numbers2)) {
  314.                         if (first) {
  315.                             wprintf(L"%ls\n", t->text[i]->sentence);
  316.                             first = 0;
  317.                             counter1++;
  318.                         }
  319.                         wprintf(L"%ls\n", t->text[j]->sentence);
  320.                         flags[j] = 0;
  321.                         counter1++;
  322.                         counter2++;
  323.                     }
  324.                 }
  325.             }
  326.             if (counter2){
  327.                 wprintf(L"\n");
  328.             }
  329.         }
  330.     }
  331.     if (!(counter1)) wprintf(L"No match!");
  332.     wprintf(L"\n");
  333.     free(flags);
  334. }
  335.  
  336.  
  337. //-------------------------------------------------------------------------------------------------
  338. //Вторая функция: сортировка предложений по кол-ву заглавных букв
  339.  
  340. int comp(const void* a, const void* b) {
  341.     Sentence* s1 = *(Sentence**)a;
  342.     Sentence* s2 = *(Sentence**)b;
  343.     int c1 = 0;
  344.     for (size_t i = 0; s1->sentence[i] != L'\0'; ++i) {             //Проверяем каждый символ предложения на то, является ли он заглавным
  345.         if (iswupper(s1->sentence[i])) {                            //если да, инкрементируем наш флаг
  346.             ++c1;
  347.         }
  348.     }
  349.     int c2 = 0;
  350.     for (size_t i = 0; s2->sentence[i] != L'\0'; ++i) {
  351.         if (iswupper(s2->sentence[i])) {
  352.             ++c2;
  353.         }
  354.     }
  355.     return c1 - c2;
  356. }
  357.  
  358. void sort(Text* t) {
  359.     qsort((void*)t->text, t->size, sizeof(Sentence*), comp);
  360. }
  361.  
  362.  
  363. //-------------------------------------------------------------------------------------------------
  364. //Третья функция: замена гласных букв на 2 следующие по алфавиту
  365.  
  366. int isVowel(wchar_t symbol) {                                                            //Проверяем, является ли символ гласной буквой
  367.     symbol = towlower(symbol);
  368.     if ((symbol == L'e') || (symbol == L'y') || (symbol == L'u') || (symbol == L'i') || (symbol == L'o') ||
  369.         (symbol == L'a') || (symbol == L'у') || (symbol == L'е') || (symbol == L'ы') || (symbol == L'ё') ||
  370.         (symbol == L'а') || (symbol == L'о') || (symbol == L'э') || (symbol == L'я') || (symbol == L'и') ||
  371.         (symbol == L'ю')) {
  372.         return 1;
  373.     }
  374.     return 0;
  375. }
  376.  
  377. void changeTwoNextSymbol(Text* t) {
  378.     for (size_t i = 0; i < t->size; ++i) {
  379.         size_t new_size = t->text[i]->size;
  380.         for (size_t j = 0; j < t->text[i]->size; ++j) {
  381.             if (isVowel(t->text[i]->sentence[j])) {
  382.                 new_size += 1;                                                  //Считаем, сколько гласных в предложении
  383.             }
  384.         }
  385.         wchar_t* s = (wchar_t*)malloc(sizeof(wchar_t) * new_size);              //Выделяем новую память в куче для измененного в дальнейшем предложения
  386.         for (size_t j = 0, k = 0; j < t->text[i]->size; ++j) {
  387.             wchar_t symbol = t->text[i]->sentence[j];
  388.             if (isVowel(symbol)) {
  389.                 wchar_t s1;
  390.                 wchar_t s2;
  391.                 if ((symbol == L'д') || (symbol == L'Д')) {                     //Следующие три проверки (if) исключительно для проверки символа Ё/ё
  392.                     if (iswupper(symbol)) {
  393.                         s1 = L'Е';
  394.                         s2 = L'Ё';
  395.                     }
  396.                     else {
  397.                         s1 = L'е';
  398.                         s2 = L'ё';
  399.                     }
  400.                     s[k++] = s1;
  401.                     s[k++] = s2;
  402.                     continue;
  403.                 }
  404.                 if ((symbol == L'е') || (symbol == L'Е')) {
  405.                     if (iswupper(symbol)) {
  406.                         s1 = L'Ё';
  407.                         s2 = L'Ж';
  408.                     }
  409.                     else {
  410.                         s1 = L'ё';
  411.                         s2 = L'ж';
  412.                     }
  413.                     s[k++] = s1;
  414.                     s[k++] = s2;
  415.                     continue;
  416.                 }
  417.                 if ((symbol == L'ё') || (symbol == L'Ё')) {
  418.                     if (iswupper(symbol)) {
  419.                         s1 = L'Ж';
  420.                         s2 = L'З';
  421.                     }
  422.                     else {
  423.                         s1 = L'ж';
  424.                         s2 = L'з';
  425.                     }
  426.                     s[k++] = s1;
  427.                     s[k++] = s2;
  428.                     continue;
  429.                 }
  430.                 if (iswupper(symbol)) {
  431.                     if ((symbol >= L'A') && (symbol <= L'Z')) {
  432.                         s1 = (symbol - L'A' + 1) % 26 + L'A';
  433.                         s2 = (s1 - L'A' + 1) % 26 + L'A';;
  434.                         s[k++] = s1;
  435.                         s[k++] = s2;
  436.                     }
  437.                     else {
  438.                         s1 = (symbol - L'А' + 1) % 32 + L'А';
  439.                         s2 = (s1 - L'А' + 1) % 32 + L'А';
  440.                         s[k++] = s1;
  441.                         s[k++] = s2;
  442.                     }
  443.                 }
  444.                 else {
  445.                     if ((symbol >= L'a') && (symbol <= L'z')) {
  446.                         s1 = (symbol - L'a' + 1) % 26 + L'a';
  447.                         s2 = (s1 - L'a' + 1) % 26 + L'a';
  448.                         s[k++] = s1;
  449.                         s[k++] = s2;
  450.                     }
  451.                     else {
  452.                         s1 = (symbol - L'а' + 1) % 32 + L'а';
  453.                         s2 = (s1 - L'а' + 1) % 32 + L'а';
  454.                         s[k++] = s1;
  455.                         s[k++] = s2;
  456.                     }
  457.                 }
  458.             }
  459.             else {
  460.                 s[k++] = symbol;
  461.             }
  462.         }
  463.         free(t->text[i]->sentence);
  464.         t->text[i]->sentence = s;
  465.         t->text[i]->size = new_size;
  466.         t->text[i]->capacity = new_size;
  467.     }
  468. }
  469.  
  470.  
  471.  
  472. //-------------------------------------------------------------------------------------------------
  473. //Четвертая функция: Замена слов
  474.  
  475. void addIndex(int** arr, size_t* size, size_t* cap, int index) {
  476.     if (!*arr) {
  477.         *cap = 10;
  478.         *arr = (int*)malloc(sizeof(int) * *cap);
  479.         (*arr)[0] = index;
  480.         *size = 1;
  481.         return;
  482.     }
  483.     if (*size + 1 <= *cap) {
  484.         (*arr)[*size] = index;
  485.         ++*size;
  486.         return;
  487.     }
  488.     *cap *= 2;
  489.     int* t = (int*)malloc(sizeof(int) * *cap);
  490.     memcpy(t, *arr, sizeof(int) * *size);
  491.     free(*arr);
  492.     t[*size] = index;
  493.     ++*size;
  494.     *arr = t;
  495. }
  496.  
  497. void changeWord(Text* t, const wchar_t* old, const wchar_t* new) {
  498.     for (size_t i = 0; i < t->size; ++i) {
  499.  
  500.         int* indexes = NULL;                                                                //Массив индексов слов в предложении
  501.         size_t indexes_size = 0;
  502.         size_t indexes_cap = 0;
  503.  
  504.         wchar_t* cpy = (wchar_t*)malloc(sizeof(wchar_t) * t->text[i]->size);
  505.         memcpy(cpy, t->text[i]->sentence, t->text[i]->size * sizeof(wchar_t));
  506.         wchar_t* buffer;
  507.         wchar_t* pt = wcstok(cpy, L" ,.", &buffer);
  508.         while (pt) {
  509.             if (wcscmp(pt, old) == 0) {
  510.                 addIndex(&indexes, &indexes_size, &indexes_cap, pt - cpy);                  //pt - cpy - получаем индекс слова в предложении
  511.             }
  512.             pt = wcstok(NULL, L" ,.", &buffer);
  513.         }
  514.         free(cpy);
  515.         if (indexes_size > 0) {
  516.             Sentence* ns = createSentence();
  517.             size_t j = 0;
  518.             size_t c = 0;
  519.             while (c != indexes_size) {
  520.                 while (j != indexes[c]) {                                                   //Добавляем символы до индекса заменяемого слова
  521.                     addOneSymbol(ns, t->text[i]->sentence[j++]);
  522.                 }
  523.                 const wchar_t* pt = new;
  524.                 while (*pt != L'\0') {                                                      //Добавляем символы заменямого слова
  525.                     addOneSymbol(ns, *pt++);
  526.                 }
  527.                 j += wcslen(old);
  528.                 ++c;
  529.             }
  530.             while (t->text[i]->sentence[j] != L'\0') {
  531.                 addOneSymbol(ns, t->text[i]->sentence[j++]);
  532.             }
  533.             addOneSymbol(ns, L'\0');
  534.  
  535.             free(indexes);
  536.  
  537.             deleteSentence(&t->text[i]);
  538.             t->text[i] = ns;
  539.         }
  540.     }
  541. }
  542.  
  543. //-------------------------------------------------------------------------------------------------
  544.  
  545.  
  546. int main() {
  547.     setlocale(LC_ALL, "");
  548.  
  549.     wprintf(L"Enter ur text: \n");
  550.     Text* t = getFullSentencesText();
  551.     printText(t);
  552.  
  553.     wchar_t old[100];
  554.     wchar_t new[100];
  555.  
  556.     int choice;
  557.     wprintf(L"Выберите функцию:\n");
  558.     wprintf(L"1) Вывести все предложения, которые являются анаграммами друг для друга;\n");
  559.     wprintf(L"2) Получить отсортированные предложения по кол-ву заглавных букв;\n");
  560.     wprintf(L"3) Получить текст, в котором каждая гласная буква будет заменена на следующие две по алфавиту;\n");
  561.     wprintf(L"4) Заменить все вхождения одного слова на другое (введенное вами);\n");
  562.     wprintf(L"5) Выход из программы;\n");
  563.     wprintf(L"6) Задание по курсу;\n");
  564.     wprintf(L"Ваш выбор:\n");
  565.  
  566.     wscanf(L"%d", &choice);
  567.     //system("clear");
  568.  
  569.     switch (choice)
  570.     {
  571.     case 1:
  572.         printAnagramms(t);
  573.         break;
  574.     case 2:
  575.         sort(t);
  576.         printText(t);
  577.         break;
  578.     case 3:
  579.         changeTwoNextSymbol(t);
  580.         printText(t);
  581.         break;
  582.     case 4:
  583.  
  584.         wprintf(L"Введите слово, которое хотите заменить: ");
  585.         wscanf(L"%ls", old);
  586.         wprintf(L"Введите слово, на которое хотите заменить: ");
  587.         wscanf(L"%ls", new);
  588.  
  589.         changeWord(t, old, new);
  590.         printText(t);
  591.         break;
  592.     case 5:
  593.         wprintf(L"Удачи!\n");
  594.         break;
  595.     case 6:
  596.  
  597.         break;
  598.     default:
  599.         wprintf(L"Введено неправильное число! Выход из программы!\n");
  600.     }
  601.  
  602.     //wprintf(L"lalalal");
  603.  
  604.     deleteText(&t);
  605.  
  606.     return 0;
  607. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement