Advertisement
Guest User

Кнут Моррис Пратт

a guest
Feb 18th, 2018
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.03 KB | None | 0 0
  1. #include <iostream>
  2. #include <fstream>
  3. #include <string>
  4. #include <vector>
  5. #include <stdlib.h>
  6.  
  7. using namespace std;
  8.  
  9. // Массив граней
  10. int* bordersArray = nullptr;
  11.  
  12. // Поиск максимальной грани для подстроки
  13. int findBorder(string input, int index, char newChar)
  14. {
  15.     if (index == 0) // подстрока из одного элемента не имеет собственных граней
  16.         return 0;
  17.     int lastBorderLength = bordersArray[index - 1]; // длина максимальной грани предыдущей подстроки
  18.  
  19.     if (input[lastBorderLength] == newChar) // если символ совпал с последним, то грань увеличилась на 1
  20.         return lastBorderLength + 1;
  21.     else if (lastBorderLength == 0) // если последняя грань была нулевой, то ничего не изменилось
  22.         return 0;
  23.     else
  24.         return findBorder(input, lastBorderLength, newChar); // ищем подстроку, в которой символ будет входить в грань
  25. }
  26.  
  27. // Построение граней
  28. void buildBordersArray(string input)
  29. {
  30.     if (bordersArray == nullptr)
  31.         bordersArray = new int[input.length()];
  32.  
  33.     for (int i = 0; i < input.length(); ++i)
  34.         bordersArray[i] = findBorder(input, i, input[i]);
  35. }
  36. // Поиск подстроки p в строке t
  37. vector<int> getSubstrings(string t, string p)
  38. {
  39.     if (bordersArray == nullptr)
  40.         bordersArray = new int[p.length()];
  41.     // Строим масссив граней для подстроки
  42.     buildBordersArray(p);
  43.  
  44.     vector<int> occurences;
  45.     int count = 0; // счетчик количества совпавших элементов
  46.  
  47.     for (int i = 0; i < t.length(); ++i)
  48.     {
  49.         if (p[count] == t[i]) // если символы совпали, увеличиваем счетчик
  50.             count +=1;
  51.         else // иначе пытаемся понять, сколько символов уже совпало - оно равно количеству граней
  52.             count = findBorder(p, count, t[i]);
  53.  
  54.         if (count == p.length()) // если количество совпавших символов равно длине подстроки
  55.         {
  56.             occurences.push_back(i + 1 - count); // добавляем вхождение
  57.             count = bordersArray[count - 1]; // ищем, сколько элементов уже совпало в гранях подстроки
  58.         }
  59.     }
  60.     return occurences;
  61. }
  62.  
  63. int main()
  64. {
  65.     string t;
  66.     string p;
  67.     vector<int> res;
  68.  
  69.     ifstream fin;
  70.     fin.open("input.txt");
  71.     if (fin.is_open())
  72.     {
  73.         getline(fin, t);
  74.         getline(fin, p);
  75.         fin.close();
  76.     }
  77.  
  78.     res = getSubstrings(t, p);
  79.  
  80.     fstream fout;
  81.     fout.open("output.txt", ios::out);
  82.     fout << res.size() << "\n";
  83.     for (std::vector<int>::const_iterator i = res.begin(); i != res.end(); ++i)
  84.         fout << *i << "\n";
  85.     fout.close();
  86.  
  87.     return 0;
  88. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement