• 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;
    }




  • 相关阅读:
    将字符串指针ps1 和 ps2之间的内存拷贝出来
    wm_copydata不等返回值处理 SendMessage SendMessageTimeout
    成为编程高手的八大奥秘
    成功老板防骗反骗技巧
    创业者怎样掌握简便的创业机会
    爱过了,恨过了,在这里留下最想对他/她说的那句话!(转)
    创业者须知的8条创业逻辑
    超越无形, 做只“一天到晚会游的鱼”
    男性的12种健康食物!
    原始商人的深度思考(二)市场准入时机的把握
  • 原文地址:https://www.cnblogs.com/hpustudent/p/2160059.html
Copyright © 2020-2023  润新知