AC自动机

//HDU   2896
//http://acm.hdu.edu.cn/showproblem.php?pid=2896  病毒侵袭
#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <string.h>
#include <queue>
using namespace std;

int web[1005][5];    

struct Trie
{
    int next[201*500][128],fail[201*500],end[201*500];
    int root,L;
    
    int newnode()
    {
        for(int i = 0;i < 128;i++) //128个ascii 
            next[L][i] = -1;
        end[L++] = 0;
        return L-1;
    }
    
    void init()
    {
        L = 0;
        root = newnode();//从0开始 
    }
    
    void insert(char buf[],int id)
    {
        int len = strlen(buf);
        int now = root;
        for(int i = 0;i < len;i++)
        {
            if(next[now][buf[i]] == -1)
            {
			    next[now][buf[i]] = newnode();  
			}
            now = next[now][buf[i]];
        }
        end[now] = id;            
    }
    
    void build()
    {
        queue<int>Q;
        fail[root] = root; 
        for(int i = 0;i < 128;i++)       
            if(next[root][i] == -1)
                next[root][i] = root;
            else
            {
                fail[next[root][i]] = root;  
                Q.push(next[root][i]);      
            }
        while( !Q.empty() )
        {
            int now = Q.front();
            Q.pop();
            for(int i = 0;i < 128;i++)
                if(next[now][i] == -1)
                    next[now][i] = next[fail[now]][i];
                else
                {
                    fail[next[now][i]]=next[fail[now]][i];    
                    Q.push(next[now][i]);
                }
        }
    }
    
    void query(char buf[],int id)
    {
        int len = strlen(buf);
        int k=1;
        int now = root;
        int res = 0;
        for(int i = 0;i < len;i++)
        {
            now = next[now][buf[i]];
            int temp = now;
            while( temp != root )
            {
                if(end[temp])
                    web[id][k++] = end[temp];
                temp = fail[temp];
            }
        }
       if(k != 1)
            sort(web[id],web[id]+k);
    }
    
};

char buf[10005];
Trie ac;

int main()
{
    int T;
    int n;
    int total=0;
    while(~scanf("%d",&T))       //我以为只要一组测试数据就可以了,没想到WA了,加上while就可以AC了
     {
	    ac.init();
        for(int i = 0;i < T;i++)
        {
            scanf("%s",buf);
            ac.insert(buf,i+1);
        }
        ac.build();
        scanf("%d",&n);
        for(int i = 0;i < n;i++)
        {
             scanf("%s",buf);
             ac.query(buf,i+1);
        }
        for(int i=1;i<=n;i++)
        {
        	if(web[i][1])
        	{
        		printf("web %d:",i);
        		total++;
			}     
        	else
        	      continue;
        	for(int j=1;web[i][j];j++)
            {
            	printf(" %d",web[i][j]);
			}
			printf("\n");
		}
		printf("total: %d\n",total);
     }
    return 0;
}


HDU  3065

http://acm.hdu.edu.cn/showproblem.php?pid=3065


#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <string.h>
#include <queue>
using namespace std;


char str[1001][55];
char buf[2000005];

struct Trie
{
    int next[2000005][128],fail[2000005],end[2000005];
    int root,L;
    
    int newnode()
    {
        for(int i = 0;i < 128;i++) //128个ascii 
            next[L][i] = -1;
        end[L++] = 0;
        return L-1;
    }
    
    void init()
    {
        L = 0;
        root = newnode();//从0开始 
    }
    
    void insert(char buf[],int id)
    {
        int len = strlen(buf);
        int now = root;
        for(int i = 0;i < len;i++)
        {
            if(next[now][buf[i]] == -1)
            {
			    next[now][buf[i]] = newnode();  
			}
            now = next[now][buf[i]];
        }
        end[now] = id;            
    }
    
    void build()
    {
        queue<int>Q;
        fail[root] = root; 
        for(int i = 0;i < 128;i++)       
            if(next[root][i] == -1)
                next[root][i] = root;
            else
            {
                fail[next[root][i]] = root;  
                Q.push(next[root][i]);      
            }
        while( !Q.empty() )
        {
            int now = Q.front();
            Q.pop();
            for(int i = 0;i < 128;i++)
                if(next[now][i] == -1)
                    next[now][i] = next[fail[now]][i];
                else
                {
                    fail[next[now][i]]=next[fail[now]][i];    
                    Q.push(next[now][i]);
                }
        }
    }
    
    
    void query(char buf[],int t)
    {
        int len = strlen(buf);
        int k=1,flag=0;
        int now = root;
        int res = 0;
        int used[1005];
        memset(used,0,sizeof(used));
        for(int i = 0;i < len;i++)
        {
            now = next[now][buf[i]];
            int temp = now;
            while( temp != root )
            {
                if(end[temp])
                {
                	used[end[temp]]++;
				}    
                temp = fail[temp];
            }
        }
        for(int j=1;j<=t;j++)
        {
            	if(used[j])
            	   printf("%s: %d\n",str[j],used[j]);
		}
    }
    
};



Trie ac;

int main()
{
    int T;
    int n;
    int total;
    while(~scanf("%d",&T))
     {
	    ac.init();
	    total=0;
        for(int i = 1;i <=T;i++)
        {
            scanf("%s",str[i]);
            ac.insert(str[i],i);
        }
        ac.build();
        scanf("%s",buf);
        ac.query(buf,T);
     }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值