zoukankan      html  css  js  c++  java
  • HDU 2222  AC自动机模板题

    1、HDU 2222

    2、题意:给出n个单词,一个字串,求有多少个单词在字串里出现了。注意给出的单词可能会重复,重复的不计。

    3、总结:入门题。在查询这里还是不太懂。

    // 2222
    #include<bits/stdc++.h>
    using namespace std;
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define F(i,a,b)  for (int i=a;i<b;i++)
    #define FF(i,a,b) for (int i=a;i<=b;i++)
    #define mes(a,b)  memset(a,b,sizeof(a))
    #define INF 0x3f3f3f3f
    typedef long long ll;
    const int N = 1e6+10;
    
    struct node
    {
        int count;
        node *next[26];
        node *fail;
        void init() {    //初始化 
            mes(next,NULL);
            count=0;
            fail=NULL;
        }
    }*q[500010];
    node *root;
    int head,tail;
    char str[N];
    
    void insert(char *keyword)
    {
        int len=strlen(keyword);
        node *p=root;
        for(int i=0; i<len; i++) {
            int index=keyword[i]-'a';
            if(p->next[index]==NULL)  p->next[index]=new node();    //注:这里要new申请内存,不要忘了 
            p=p->next[index];
        }
        p->count++;
    }
    
    void build_ac_automation()    //初始化fail指针,BFS
    {
        q[tail++]=root; 
        while(head!=tail) {
            node *p=q[head++];    //弹出队头
            node *temp=NULL;
            for(int i=0; i<26; i++) {
                if(p->next[i]!=NULL) {
                    if(p==root)    p->next[i]->fail=root;    //第一个元素fail必指向根
                    else {
                        temp=p->fail;
                        while(temp) {    //2种情况结束:匹配为空or找到匹配
                            if(temp->next[i]) {        //找到匹配
                                p->next[i]->fail=temp->next[i];    
                                break;
                            }
                            temp=temp->fail;
                        }
                        if(!temp) p->next[i]->fail=root;     //为空则从头匹配
                    }
                    q[tail++]=p->next[i];    //入队
                }
            }
        }
    }
    
    void query()        //扫描,查询这里还是没太搞懂 
    {
        int i=0,cnt=0,index,len=strlen(str);
        node *p=root;
        for(int i=0; str[i]; i++) {
            index=str[i]-'a';
            while(p->next[index]==NULL&&p!=root)  p=p->fail;    //跳转失败指针
            p=p->next[index];
            if(p==NULL)  p=root;
            node *temp=p;    //p即是找到的当前结点,p不动,temp计算后缀串
            while(temp!=root&&temp->count!=-1) {
                cnt+=temp->count;
                temp->count=-1;
                temp=temp->fail;
            }
        }
        printf("%d
    ", cnt);
    }
    
    int main()
    {
        int T,n;
        char keyword[100];
        scanf("%d", &T);
        while(T--) {
            head=tail=0;
            scanf("%d", &n);
            getchar();
            root=new node();
            while(n--) {
                gets(keyword);
                insert(keyword);
            }
            build_ac_automation();
            gets(str);
            query();
        }
    
        return 0;
    }
    View Code
  • 相关阅读:
    JVM和HotSpot
    java中的四种引用类型
    垃圾回收与算法
    Full GC
    JVM内存结构
    事务不同的隔离级别实现原理
    事务的隔离级别
    jQuery后续和 前端框架Bootstrap
    jQuery
    BOM和DOM操作
  • 原文地址:https://www.cnblogs.com/sbfhy/p/6051155.html
Copyright © 2011-2022 走看看