Advertisement
smatskevich

Seminar13

May 12th, 2022
803
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.91 KB | None | 0 0
  1. #include <iostream>
  2. #include <queue>
  3. #include <unordered_set>
  4. #include <vector>
  5.  
  6. struct Node {
  7.   char Letter;  // Буква, по которой пришли в узел.
  8.   bool IsTerminal = false;
  9.   std::vector<Node*> Children;
  10.   Node* Parent;
  11.   Node* SuffLink = nullptr;
  12.  
  13.   Node(Node* parent, char letter) : Parent(parent), Letter(letter) {}
  14. };
  15.  
  16. class Trie {
  17.  public:
  18.   Trie() : start(new Node(nullptr, 0)) { start->SuffLink = start; }
  19.   ~Trie() {
  20.     std::unordered_set<Node*> all;
  21.     all.insert(start);
  22.     std::queue<Node*> q;
  23.     q.push(start);
  24.     while (!q.empty()) {
  25.       Node* cur = q.front(); q.pop();
  26.       for (Node* c : cur->Children) {
  27.         if (c != nullptr && !all.count(c)) {
  28.           q.push(c);
  29.           all.insert(c);
  30.         }
  31.       }
  32.     }
  33.     for (Node* x : all) delete x;
  34.   }
  35.   void Add(const std::string& s);
  36.   void Print() const;
  37.   void AhoCorasik(const std::string& text);
  38.  
  39.  private:
  40.   Node* start;
  41.   void DFSPrint(std::string& s, Node* current) const;
  42.   Node* GoTo(Node* q, char a);
  43.   Node* F(Node* q);
  44. };
  45.  
  46. void Trie::AhoCorasik(const std::string& text) {
  47.   Node* q = start;
  48.   for (int i = 0; i < text.size(); ++i) {
  49.     std::cout << i << "\n";
  50.     q = GoTo(q, text[i]);
  51.     // Выдать все терминальные, доступные по суфф.ссылкам.
  52.     for (Node* x = q; x != start; x = F(x)) {
  53.       if (x->IsTerminal) std::cout << "Found pattern with ending symbol " << x->Letter << "\n";
  54.     }
  55.   }
  56. }
  57. Node* Trie::GoTo(Node* q, char a) {
  58.   if (q->Children.empty()) q->Children.assign(256, nullptr);
  59.   if (q->Children[a]) return q->Children[a];
  60.   if (!q->Parent) return q->Children[a] = q;
  61.   return q->Children[a] = GoTo(F(q), a);
  62. }
  63. Node* Trie::F(Node* q) {
  64.   if (q->SuffLink) return q->SuffLink;
  65.   if (q->Parent == start) return q->SuffLink = start;
  66.   return q->SuffLink = GoTo(F(q->Parent), q->Letter);
  67. }
  68. // hello
  69. // hell
  70. void Trie::Add(const std::string& s) {
  71.   Node* cur_node = start;
  72.   for (int i = 0; i < s.size(); ++i) {
  73.     if (cur_node->Children.empty()) cur_node->Children.assign(256, nullptr);
  74.     if (!cur_node->Children[s[i]]) {
  75.       cur_node->Children[s[i]] = new Node(cur_node, s[i]);
  76.     }
  77.     cur_node = cur_node->Children[s[i]];
  78.     cur_node->IsTerminal |= (i == s.size() - 1);
  79.   }
  80. }
  81.  
  82. void Trie::Print() const {
  83.   std::string s;
  84.   DFSPrint(s, start);
  85. }
  86.  
  87. void Trie::DFSPrint(std::string& s, Node* current) const {
  88.   if (current->IsTerminal) std::cout << s << "\n";
  89.   for (int i = 0; i < current->Children.size(); ++i) {
  90.     if (current->Children[i]) {
  91.       s.push_back(char(i));
  92.       DFSPrint(s, current->Children[i]);
  93.       s.pop_back();
  94.     }
  95.   }
  96. }
  97.  
  98. int main() {
  99.   Trie trie;
  100.   int n = 0; std::cin >> n;
  101.   for (int i = 0; i < n; ++i) {
  102.     std::string s;
  103.     std::cin >> s;
  104.     trie.Add(s);
  105.   }
  106.   trie.Print();
  107.   std::string text; std::cin >> text;
  108.   trie.AhoCorasik(text);
  109.   return 0;
  110. }
  111.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement