AC自动机

struct node
{
  vector<int> exist;
  node *fail;
  node *child[26];
  node()
  {
    fail = NULL;
    for (int i = 0; i < 26; i++)
    {
      child[i] = NULL;
    }
  }
  
};

void insert(char *s, node *root) {
  int len = strlen(s);
  for(int i = 0; i < len; ++i) {
    int c = s[i] - 'a';
    if(root->child[c] == NULL) {
      root->child[c] = new node();
    }
    root = root -> child[c];
  }
  root -> exist.push_back(len);
}

void make_fail(node *root) {
  root->fail = NULL;
  queue<node*> q;
  for(int i = 0; i < 26; i++) {
    if(root -> child[i] != NULL) {
      root->child[i] -> fail = root;
      q.push(root -> child[i]);
    }
  }
  while(!q.empty()) {
    node *x = q.front(); q.pop();
    for(int i = 0; i < 26; ++i) {
      if(x -> child[i] != NULL) {
        node *fafail = x -> fail;
        while(fafail != NULL && fafail -> child[i] == NULL) fafail = fafail -> fail;
        if(fafail == NULL) x -> child[i] -> fail = root;
        else  {
          x -> child[i] ->fail = fafail -> child[i];
          if(x -> child[i] -> fail -> exist . size() > 0) {
            int n = x -> child[i] -> fail -> exist . size();
            for(int j = 0; j < n; ++j) {
              x->child[i]->exist.push_back(x->child[i]->fail->exist[j]);
            }
          }
        }
        q.push(x->child[i]);
      }
    }
  }
}

int many(char *s, node *root) {
  int len = strlen(s);
  int ans = 0;
  node *now = root;
  for(int i = 0; i < len; i++) {
    int c = s[i] - 'a';
    while(now -> child[c] == NULL && now -> fail != NULL) {
      now = now -> fail;
    }
    if(now -> child[c] != NULL) {
      now = now -> child[c];
    }
    ans += now->exist.size();
  }
  return ans;
}

int main()
{
  int q;
  char s[30];
  node *root = new node();
  cin >> q;
  while (q--)
  {
    cin >> s;
    insert(s, root);
  }
  make_fail(root);
  cin >> s;
  cout << many(s,root);
  delete root;
  return 0;
}
posted @ 2021-03-16 19:50  执梦之花  阅读(41)  评论(0编辑  收藏  举报