Keywords Search(查找关键字)


hdoj 2222

题目大意:给出一些字符串 ,再给出一段文字,问文字中出现多少个单词

解决:AC自动机

 

#include <iostream>
#include <cstring>
#include <queue>
#include <cstdio>
using namespace std;
#define s  scanf
int top;
struct node
{
    int cnt;
    int fail;
    int next[26];
};
node tree[400000];
char mai[1000005];
void init()
{
    top=1;
    memset(tree[0].next,0,sizeof(tree[0].next));
   //刚开始的时候初始化,是在node的构造函数中实现的,但是由于是多组测试数据,所以
  //错误了好几次这次,就应该在初始化,和需要新的结点的时候在初始化
    tree[top].cnt=0;
}
void insert_trie(char str[])
{
    int id,i=0;
    while(*str)
    {
        id=*str-'a';
        if(!tree[i].next[id])
        {
            tree[i].next[id]=top;
            memset(tree[top].next,0,sizeof(tree[top].next));
            tree[top].cnt=0;
            top++;
        } 
        i=tree[i].next[id];
        str++;
    }
    tree[i].cnt++;
}
void build_fail()
{
    tree[0].fail=-1;
    queue<int> q;
    q.push(0);
    while(!q.empty())
    {
        int now=q.front();
        q.pop();
        for(int i=0;i<26;i++)
        {
            int tmp=tree[now].next[i];
            if(tmp)
            {
                int p;
                for(p=tree[now].fail;p!=-1;p=tree[p].fail)
                   if(tree[p].next[i])
                   {
                        tree[tmp].fail=tree[p].next[i];
                        break;
                   }
                   
                if(p==-1){tree[tmp].fail=0;}
                q.push(tmp);
            }
        }
    }
}
void query(char str[])
{
    int id,sum=0,p=0;
    while(*str)
    {
        id=*str-'a';
      //不匹配的情况,找到根节点,或者是找到匹配的地方
        while(tree[p].next[id]==0 && p)p=tree[p].fail;
        if(tree[p].next[id]==0)p=0;
        else p=tree[p].next[id];
    //匹配或者是根节点的情况,沿着fail一直找到跟,将所有的一该字母结束的串的情况 都   算上。
        int tmp=p;   
        while(tmp && tree[tmp].cnt)
        {
            sum+=tree[tmp].cnt;
            tree[tmp].cnt=0;
            tmp=tree[tmp].fail;
        }
        str++;
    }
    printf("%d\n",sum);
}

int main()
{
    int icase;
    s("%d",&icase);
    while(icase--)
    {
        init();
        int n;
        char str[60];
        s("%d",&n);
        while(n--)
        {
            s("%s",str);
            insert_trie(str);
        }
        build_fail();
        s("%s",mai);
        query(mai);
    }
 //   system("pause");
    return 0;
}




原文地址:https://www.cnblogs.com/hpustudent/p/2160059.html