Guest User

Aho-Corasick

a guest
Sep 11th, 2013
278
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.75 KB | None | 0 0
  1. #include <iostream>
  2. #include <queue>
  3. #include <cstring>
  4. #include <string>
  5. #include <vector>
  6. using namespace std;
  7.  
  8. vector<string> words;
  9. int state = 0;
  10. int g[1<<17][26];
  11. int green[1<<17];
  12. int blue[1<<17];
  13. vector<int> fin[1<<17];
  14.  
  15.  
  16. void BuildMachine()
  17. {
  18.     memset(g,-1,sizeof(g));
  19.     memset(blue,-1,sizeof(blue));
  20.     memset(green,-1,sizeof(green));
  21.  
  22.     string currentWord;
  23.     int currentState;
  24.     int c;
  25.     //make trie
  26.     state = 1;
  27.     for(int i=0; i<words.size(); i++)
  28.     {
  29.         currentState = 0;
  30.         currentWord = words[i];
  31.         //cout << "At word "  << i << endl;
  32.         for(int j=0; j<currentWord.size(); j++)
  33.         {
  34.             c = currentWord[j] - 'a';
  35.             //cout << "      "  << currentState << ' ' << g[currentState][c] << ' ' << state << endl;
  36.             if(g[currentState][c] == -1) {
  37.                 g[currentState][c] = state++;
  38.             }
  39.             currentState = g[currentState][c];
  40.         }
  41.         fin[currentState].push_back(i);
  42.     }
  43.  
  44.     //cout << state << endl;
  45.  
  46.     queue<int> q;
  47.  
  48.     for(int i=0; i<26; i++){
  49.         if(g[0][i] == -1){
  50.             g[0][i] = 0;
  51.         }
  52.         if(g[0][i] != -1 && g[0][i] != 0)
  53.         {
  54.             blue[g[0][i]]  = 0;
  55.             q.push(g[0][i]);
  56.         }
  57.     }
  58.  
  59.     //make sufix arcs
  60.     vector<int> greens;
  61.     int current;
  62.     int blueArc;
  63.     while(!q.empty())
  64.     {
  65.         current = q.front(); q.pop();
  66.         for(int i=0; i<26; i++)
  67.         {
  68.             greens.clear();
  69.             if(g[current][i] != -1) {
  70.                 blueArc = blue[current];
  71.                 while(g[blueArc][i] == -1) blueArc = blue[blueArc];
  72.  
  73.                 blueArc = g[blueArc][i];
  74.                 blue[g[current][i]] = blueArc;
  75.                 q.push(g[current][i]);
  76.  
  77.                 //cout << current << '-'  << g[current][i] << ' '  << blueArc << endl;
  78.  
  79.                 while(fin[blueArc].size() == 0){
  80.                     greens.push_back(blueArc);
  81.                     blueArc = blue[blueArc];
  82.                     if(blueArc  == 0) break;
  83.                 }
  84.                 if(blueArc == 0) continue;
  85.                 green[g[current][i]] = blueArc;
  86.                 for(int j=0; j<greens.size(); j++) green[greens[j]] = blueArc;
  87.             }
  88.         }
  89.     }
  90. }
  91.  
  92. int nextState(int current, char input)
  93. {
  94.     int c = input - 'a';
  95.     //cout << c << '-' << g[current][c] << endl;
  96.     if(g[current][c] != -1) return g[current][c];
  97.  
  98.     int blueArc = blue[current];
  99.     while(g[blueArc][c] == -1) blueArc = blue[blueArc];
  100.  
  101.     return g[blueArc][c];
  102. }
  103.  
  104. struct match
  105. {
  106.     int pos;
  107.     int id;
  108.  
  109.     match(){}
  110.  
  111.     match(int a, int b)
  112.     {
  113.         id = a;
  114.         pos = b;
  115.     }
  116. };
  117.  
  118. vector<match> output;
  119.  
  120.  
  121.  
  122. int main()
  123. {
  124.     int n;
  125.     cout << "Enter number of words: ";
  126.     cin >> n;
  127.  
  128.     cout << "Enter words:\n";
  129.  
  130.     string s;
  131.     for(int i=0; i<n; i++) {
  132.         cin >> s;
  133.         words.push_back(s);
  134.     }
  135.  
  136.     BuildMachine();
  137.  
  138.     cout << "Enter input text: \n";
  139.     cin >> s;
  140.     int m = s.size();
  141.  
  142.     int currentState = 0;
  143.     int cs = 0;
  144.     for(int i=0; i<m; i++)
  145.     {
  146.         cs = nextState(cs,s[i]);
  147.         //cout << "At pos: "  << i << ' ' << " State: " << currentState << endl;
  148.         currentState = cs;
  149.         while(currentState != -1)
  150.         {
  151.             for(int j=0; j<fin[currentState].size(); j++)
  152.                 output.push_back(match(fin[currentState][j],i));
  153.             currentState = green[currentState];
  154.         }
  155.     }
  156.  
  157.     //cout << "Entered\n";
  158.     cout << "Found " << output.size() << " matches!\n";
  159.  
  160.     for(int i=0; i<output.size(); i++)
  161.     {
  162.         cout << words[output[i].id] << " at end position "  << output[i].pos << endl;
  163.     }
  164.  
  165.     return 0;
  166. }
Advertisement
Add Comment
Please, Sign In to add comment