Created
          August 20, 2012 16:56 
        
      - 
      
- 
        Save ZhanruiLiang/3405768 to your computer and use it in GitHub Desktop. 
    AC automaton implement in C++
  
        
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | #include<iostream> | |
| #include<sstream> | |
| #include<string> | |
| #include<queue> | |
| #include<cstdio> | |
| #include<cstring> | |
| #include<cctype> | |
| #include<vector> | |
| #include<cstring> | |
| #include<algorithm> | |
| #include<vector> | |
| #define For(i, n) for(i = 0; i < n; i++) | |
| #define Forr(i, l, n) for(i = l; i < n; i++) | |
| typedef long long LL; | |
| using namespace std; | |
| const int N = 1002; | |
| const char SEP = '$'; | |
| const int D[8][2] = {{-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}, {-1, -1}}; | |
| // AC automaton code ///////////////////////////////////////////////////////// | |
| // Usage: | |
| // *) start_build() | |
| // *) add_string(s1, n1) | |
| // *) add_string(s2, n2) | |
| // ... | |
| // *) end_build() | |
| // | |
| const int E = 26; | |
| struct ACNode{ | |
| int nexts[E]; | |
| int out; | |
| int fail; | |
| ACNode():out(0){}; | |
| }; | |
| ACNode nodes[100000]; | |
| class ACAuto{ | |
| public: | |
| int ncnt; | |
| int st0; | |
| int aux; | |
| inline int char2code(char c){ return c - 'a'; } | |
| inline char code2char(int code){ return 'a' + code; } | |
| int new_node(){ | |
| int i; | |
| For(i, E) nodes[ncnt].nexts[i] = -1; | |
| nodes[ncnt].fail = -1; | |
| nodes[ncnt].out = 0; | |
| return ncnt++; | |
| } | |
| inline int set_transition(int s, char c, int s1){ | |
| nodes[s].nexts[char2code(c)] = s1; | |
| } | |
| inline int get_transition(int s, char c){ | |
| return nodes[s].nexts[char2code(c)]; | |
| } | |
| void start_build(){ | |
| int i; | |
| ncnt = 0; | |
| aux = new_node(); | |
| st0 = new_node(); | |
| For(i, E) nodes[aux].nexts[i] = st0; | |
| nodes[st0].fail = aux; | |
| } | |
| void add_string(const char*s, int n){ | |
| int st1, st2; | |
| int i; | |
| char c; | |
| st1 = st0; | |
| For(i, n){ | |
| c = s[i]; | |
| st2 = get_transition(st1, c); | |
| if(st2 == -1){ | |
| st2 = new_node(); | |
| set_transition(st1, c, st2); | |
| } | |
| st1 = st2; | |
| } | |
| // the end of the word s | |
| nodes[st1].out += 1; | |
| } | |
| int get_through(int s, char c){ | |
| int s1, s0; | |
| s0 = s; | |
| while(1){ | |
| s1 = get_transition(s, c); | |
| if(s1 != -1){ | |
| #ifndef DEBUG | |
| //lazy | |
| set_transition(s0, c, s1); | |
| #endif | |
| return s1; | |
| }else s = nodes[s].fail; | |
| } | |
| } | |
| void end_build(){ | |
| queue<int> que; | |
| int st1, st2, st3; | |
| char c, ci; | |
| que.push(st0); | |
| while(!que.empty()){ | |
| st1 = que.front(); | |
| que.pop(); | |
| For(ci, E){ | |
| c = code2char(ci); | |
| st2 = get_transition(st1, c); | |
| if(st2 != -1){ | |
| que.push(st2); | |
| st3 = get_through(nodes[st1].fail, c); | |
| nodes[st2].fail = st3; | |
| // union end of words that recognized by st2 | |
| // nodes[st2].out += nodes[st3].out; | |
| } | |
| } | |
| } | |
| } | |
| #ifdef DEBUG | |
| void print_tire(char c = '^', int st = -2, int indent = 0){ | |
| if(st == -2) st = st0; | |
| else if(st == -1) return; | |
| int j; | |
| For(j, indent) cout << ' '; | |
| string s; stringstream ss; | |
| printf("(%c) st:[%d] out:[%d] fail:{%d}\n", c, st, nodes[st].out, nodes[st].fail); | |
| For(j, E){ | |
| c = code2char(j); | |
| print_tire(c, get_transition(st, c), indent+4); | |
| } | |
| } | |
| #endif | |
| }; | |
| /////////////////// end of AC automaton code ////////////////////////////////////////// | |
| ACAuto ac; | |
| int main(){ | |
| int n, i; | |
| string s; | |
| cin >> n; | |
| ac.start_build(); | |
| For(i, n){ | |
| cin >> s; | |
| ac.add_string(s.c_str(), s.size()); | |
| } | |
| ac.end_build(); | |
| ac.print_tire(); | |
| } | 
  
    Sign up for free
    to join this conversation on GitHub.
    Already have an account?
    Sign in to comment