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;

}




你可能感兴趣的:(search)