zoukankan      html  css  js  c++  java
  • AC自动机跟随Kuangbing学习笔记


    http://www.cnblogs.com/kuangbin/p/3164106.html kuangbin的博客

    第一段代码基本是COPY kuangbin的..


    1、HDU 2222 Keywords Search    最基本的入门题了

    就是求目标串中出现了几个模式串。

    很基础了。使用一个int型的end数组记录,查询一次。

    //======================
    // HDU 2222
    // 求目标串中出现了几个模式串
    //输入 
    //1
    //5
    //she
    //he
    //say
    //shr
    //her
    //yasherhs 
    //====================
    #include<stdio.h>
    #include<algorithm>
    #include<iostream>
    #include<string.h>
    #include<queue>
    using namespace std;
    
    struct Trie
    {
    	int next[500010][26],fail[500010],end[500010];
    	int root,L;
    	int newnode()
    	{
    		for(int i=0;i<26;i++)
    			next[L][i]=-1;
    		end[L++]=0;
    		return L-1; 
    	}
    	void init()
    	{
    		L=0;
    		root=newnode();
    	} 
    	void insert(char buf[])
    	{
    		int len = strlen(buf);
    		int now = root;
    		for(int i=0;i<len;i++)
    		{
    			if(next[now][buf[i]-'a']==-1)
    			 	next[now][buf[i]-'a']=newnode();
    			now=next[now][buf[i]-'a'];
    		}
    		end[now]++;
    	}
    	void build()
    	{
    		queue<int>Q;
    		fail[root]=root;
    		for(int i=0;i<26;i++)
    			if(next[root][i]==-1)
    				next[root][i]=root;						//匹配失效回到根节点继续匹配 
    			else  
    			{
    				fail[next[root][i]]=root;			    //第一层的失败指针指向root 
    				Q.push(next[root][i]);					//加入队列    
    			}
    		while(!Q.empty())
    		{
    			int now=Q.front();
    			Q.pop();
    			for(int i=0;i<26;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]); 
    				}
    			}
    		} 
    	}
    	int query(char buf[])
    	{
    		int len=strlen(buf);
    		int now=root;
    		int res=0;
    		for(int i=0;i<len;i++)
    		{ 
    			now=next[now][buf[i]-'a'];
    			int temp=now;
    			while(temp!=root)
    			{
    				res+=end[temp];
    				end[temp]=0;
    				temp=fail[temp];
    			} 
    		} 
    		return res;
    	} 
    	void debug()
    	{
    		for(int i=0;i<L;i++)
    		{
    			           printf("id = %3d,fail = %3d,end = %3d,chi = [",i,fail[i],end[i]);
             			   for(int j = 0;j < 26;j++)
               			     printf("%2d",next[i][j]);
             			   printf("]
    ");
    		} 
    	} 
    };
    char s[300];
    char buff[1000005];
    	Trie ac;
    void input()
    {
    	int n;
    	cin>>n;
    	ac.init();
    	for(int i=1;i<=n;i++)
    	{
    		scanf("%s",s);
    		ac.insert(s);
    	}
    	ac.build();
    }
    int main()
    {
    	int T;
    	cin>>T;
    	while(T--)
    	{
    		input();
    		scanf("%s",buff);
    		printf("%d
    ",ac.query(buff));
    	}
    }
    
     
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    



  • 相关阅读:
    Ubuntu系统
    demo日常报错
    python 实现两个多维数组去重处理
    奔跑检测
    安装Win11如何绕过TPM2.0的安全限制?
    Nginx的Rewrite
    gvim 配置
    Tokyo Cabinet和Tokyo Tyrant及PHP扩展包的安装
    fm rf 删除 恢复
    提高页面loadtime的几个方法
  • 原文地址:https://www.cnblogs.com/zy691357966/p/5480324.html
Copyright © 2011-2022 走看看