dimon-torchila

Untitled

Sep 12th, 2022
171
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.65 KB | None | 0 0
  1. #include <iostream>
  2. #include <string>
  3. #include <vector>
  4. #include <cctype>
  5. #include <fstream>
  6. #include <clocale>
  7. #include <ctime>
  8. using namespace std;
  9.  
  10. class ofwords   // класс для хранения количества слов каждой длины
  11. {
  12. public:
  13.  
  14.     int length = 0;
  15.     int count = 0;
  16. };
  17.  
  18.  
  19. void doMerge(vector<string>& words, int left, int right) // сортировка слиянием, принимает правый и левый индексы
  20. {
  21.     vector<string> mid_word;                             // создание и заполнение промежуточного (сортируемая часть соновного) вектора
  22.     for (int i = 0; i <= (right - left); i++)
  23.     {
  24.         mid_word.push_back(words[left + i]);
  25.     }
  26.     int i = 0, j = (right - left) / 2 + 1, q = left;
  27.     while (i <= ((right - left) / 2) or j <= (right - left))
  28.     {
  29.         if (i <= ((right - left) / 2) and j <= (right - left)) // i - проходится по левой половине вектора, j - по правой
  30.         {
  31.             if (mid_word[i].size() > mid_word[j].size())       // сравнивает и ставит минимальное в основной вектор
  32.             {
  33.                 words[q] = mid_word[i];
  34.                 q++;
  35.                 i++;
  36.             }
  37.             else
  38.             {
  39.                 words[q] = mid_word[j];
  40.                 q++;
  41.                 j++;
  42.             }
  43.         }
  44.         else if (j > (right - left))                           // вставляет оставшиеся, если в одной из половин слова закончились
  45.         {
  46.             words[q] = mid_word[i];
  47.             q++;
  48.             i++;
  49.         }
  50.         else if (i > ((right - left) / 2))
  51.         {
  52.             words[q] = mid_word[j];
  53.             q++;
  54.             j++;
  55.         }
  56.     }
  57.  
  58. }
  59.  
  60. void sortMerge(vector<string>& words, int left, int right)  // рекурсивное разделение вектора на две части
  61. {
  62.     if (left != right)
  63.     {
  64.         sortMerge(words, left, left + ((right - left) / 2));
  65.         sortMerge(words, left + ((right - left) / 2) + 1, right);// делит на две части
  66.         doMerge(words, left, right);                             // сортирует две отсортированные глубже части
  67.     }
  68. }
  69.  
  70. string redactString(string word) // удаляет из слова несортируемые символы
  71. {
  72.     for (int i = 0; i < word.length(); i++)
  73.     {
  74.         if (!(isalnum(word[i]) and word[i] <= 127))  // если не латинская буква и не цифра, удаляет
  75.         {
  76.             if (word.length() == 1)
  77.                 word.erase(i);                       // если длина слова "1", другие параметры для erase
  78.             else {
  79.                 word.erase(i, 1);
  80.                 i--;                                 // после удаления символа следующий символ встает на место с индексом удаленного
  81.             }                                        // поэтому чтобы пройтись и по этому символу, i на след. шаге нужно оставить таким же
  82.         }
  83.     }
  84.     return word;
  85. }
  86.  
  87. void recieveInput(vector<string>& words, string& path) // проверяет корректность введенного с консоли пути к файлу
  88. {                                                     // и при ошибке просит ввести заново
  89.     ifstream orig_file;
  90.     bool check = false;
  91.     while (check == false) {
  92.         check = true;
  93.         orig_file.open(path);
  94.         if (!orig_file.is_open())
  95.         {
  96.             cout << "Error accessing the file." << endl;
  97.             cout << "Введите полный путь к текстовому файлу" << endl;
  98.             getline(cin, path);
  99.             check = false;
  100.         }
  101.     }
  102.  
  103.  
  104.     while (!orig_file.eof()) // пока файл не закончится, добавляет каждое слово (разделенное пробелами или переносми строки) в вектор
  105.     {
  106.         string new_word;
  107.         orig_file >> new_word;
  108.         new_word = redactString(new_word);
  109.         if (new_word.length() > 0) {
  110.             words.push_back(new_word);
  111.         }
  112.     }
  113.     orig_file.close();
  114. }
  115.  
  116. void recordResult(vector<string>& words, char origpathnum) // записывает в (созданный на основе названия оригинального файла) файл остортированный вектор слов
  117. {
  118.     ofstream result;
  119.     string txt = ".txt";
  120.     string respath = "D:\\practice_txt_files\\result";
  121.     respath += origpathnum + txt;
  122.     result.open(respath);
  123.     for (int i = 0; i < words.size(); i++)
  124.         result << words[i] << endl;
  125.     result.close();
  126. }
  127.  
  128. int findInVector(vector <ofwords> vtr, int number)  // проверяет наличие в векторе ofwords (хранящих данные о количестве слов каждой длины)
  129. {                                                   // ofwords с конкретной длиной и возвращает индекс, или -1, если такого еще нет
  130.     for (int i = 0; i < vtr.size(); i++)
  131.     {
  132.         if (vtr[i].length == number)
  133.             return i;
  134.     }
  135.     return -1;
  136. }
  137.  
  138. void countAllLengths(vector<string>& words, vector<ofwords>& word_length_count) // сохраняет данные о количестве слов каждой длины,
  139. {                                                                               // проходясь по отсортированному массиву
  140.     for (int i = 0; i < words.size(); i++)
  141.     {
  142.         int finded = findInVector(word_length_count, words[i].length());        // если слова такой длины еще не попадалось, добавляет в вектор
  143.         if (finded == -1)                                                       // ofwords этой длины c count = 1
  144.         {
  145.             ofwords ow;
  146.             ow.length = words[i].length();
  147.             ow.count++;
  148.             word_length_count.push_back(ow);
  149.         }
  150.         else
  151.         {
  152.             word_length_count[finded].count++;                                   // если есть, увеличивает счетчик
  153.         }
  154.     }
  155. }
  156.  
  157. void doAndRecordAnalysis(vector<string>& words, int time, string origpath)       // выводит в (созанный на основе оригинаьного файла) файл и консоль
  158. {
  159.     ifstream orig_file;
  160.     ofstream analysis;
  161.     string txt = ".txt";
  162.     string anpath = "D:\\practice_txt_files\\analysis";
  163.     anpath += origpath[origpath.length() - 5] + txt;                             // данные о тексте:
  164.     analysis.open(anpath);
  165.     cout << "Исходный текст: " << endl;
  166.     analysis << "Исходный текст: " << endl;
  167.     orig_file.open(origpath);
  168.     while (!orig_file.eof())                                                     // исходный текст по строкам копирует из оригинального файла
  169.     {
  170.         string line;
  171.         getline(orig_file, line);
  172.         cout << line << endl;
  173.         analysis << line << endl;
  174.     }
  175.     orig_file.close();                                                           // условия варианта
  176.     cout << endl << "Вариант 18: латиница, по кол-ву символов в слове, по убыванию, учитывать числа, сортировка слиянием.\nКоличество слов: " << words.size()
  177.         << endl << "Время сортировки: " << time << " мс\nСтатистика (количество слов каждой длины):" << endl;
  178.     analysis << endl << "Вариант 18: латиница, по кол-ву символов в слове, по убыванию, учитывать числа, сортировка слиянием.\nКоличество слов: " << words.size()
  179.         << endl << "Время сортировки: " << time << " мс\nСтатистика (количество слов каждой длины):" << endl;
  180.     vector<ofwords> word_length_count;                                           // время сортировки
  181.     countAllLengths(words, word_length_count);                                   // данные о количестве слов каждой длины
  182.     for (int i = word_length_count.size() - 1; i >= 0; i--)
  183.     {
  184.         cout << word_length_count[i].length << " - " << word_length_count[i].count << endl;
  185.         analysis << word_length_count[i].length << " - " << word_length_count[i].count << endl;
  186.     }
  187. }
  188.  
  189. int main()
  190. {
  191.     setlocale(LC_ALL, "");
  192.     cout << "Введите полный путь к текстовому файлу" << endl;
  193.     string path;                                                                 // принимает путь к оригинальному файлу и сохраняет его
  194.     getline(cin, path);
  195.  
  196.     vector <string> words;
  197.  
  198.     recieveInput(words, path);
  199.  
  200.     int time0 = clock();
  201.     sortMerge(words, 0, words.size() - 1);
  202.     int time = clock() - time0;                                                  // вычисляет время сортировки
  203.  
  204.     recordResult(words, path[path.length() - 5]);
  205.  
  206.     doAndRecordAnalysis(words, time, path);
  207.  
  208. }
  209.  
Add Comment
Please, Sign In to add comment