zoukankan      html  css  js  c++  java
  • [hdu2222] Keywords Search

    Description

    给定 (n) 个长度不超过 (50) 的由小写英文字母组成的单词准备查询,以及一篇长为 (m) 的文章,问:文中出现了多少个待查询的单词。多组数据。

    Input

    第一行一个整数 (T),表示数据组数;
    对于每组数据,第一行一个整数 (n),接下去 (n) 行表示 (n) 个单词,最后一行输入一个字符串,表示文章。

    Output

    对于每组数据,输出一个数,表示文中出现了多少个待查询的单词。

    Sample Input

    1
    5
    she
    he
    say
    shr
    her
    yasherhs
    

    Sample Output

    3
    

    Hint

    对于全部数据,(1le nle 10^4,1le mle 10^6)

    题解

    AC自动机模板题

    #include<iostream>
    #include<cstdlib>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<set>
    #include<map>
    #include<bitset>
    #include<vector>
    #include<iomanip>
    using namespace std;
    
    const int Size=26,Maxn=500005;
    struct Trie{
    	int son[Maxn][Size],fail[Maxn],cnt[Maxn];
    /*	son[i][j]存放 父节点的下标为i 的子节点字符为j的下标
    	fail[i]下标为i的节点如果失配放回的下标
    	cnt[i]从根节点到下标为i的节点所构成的模式串的个数
    */	int id;
    	Trie(){id=0;}//构造函数
    	int Newnode()//新建一个节点
    	{
    		for(int i=0;i<Size;++i) son[id][i]=-1;
    		cnt[id]=0;
    		return id++;
    	}
    	void Init()//初始化
    	{
    		id=0,Newnode();
    	}
    	void Insert(char s[])//把模式串s插入到Trie树
    	{
    		int l=strlen(s),now=0,k;
    		for(int i=0;i<l;++i)
    		{
    			k=s[i]-'a';
    			if(son[now][k]==-1) son[now][k]=Newnode();
    			now=son[now][k];
    		}
    		++cnt[now];
    	}
    	queue<int> Q;
    	void Build()//构建Fail指针
    	{
    		while(!Q.empty()) Q.pop();
    		fail[0]=0;
    		for(int i=0;i<Size;++i)
    			if(son[0][i]==-1) son[0][i]=0;
    			else
    			{
    				fail[son[0][i]]=0;
    				Q.push(son[0][i]);
    			}
    		int now;
    		while(!Q.empty())
    		{
    			now=Q.front(); Q.pop();
    			for(int i=0;i<Size;++i)
    				if(son[now][i]==-1) son[now][i]=son[fail[now]][i];
    				else
    				{
    					fail[son[now][i]]=son[fail[now]][i];
    					Q.push(son[now][i]);
    				}
    		}
    	}
    	int Query(char s[])//文本串来匹配
    	{
    		int len=strlen(s),now=0,Res=0;
    		for(int i=0;i<len;++i)
    		{
    			now=son[now][s[i]-'a'];
    			int tmp=now;
    			while((tmp)&&(cnt[tmp]!=-1))
    			{
    				Res+=cnt[tmp],
    				cnt[tmp]=-1,
    				tmp=fail[tmp];
    			}
    		}
    		return Res;
    	}
    }AC;
    char s[Maxn+Maxn];
    
    int main()
    {
    	int T,n;
    	for(scanf("%d",&T);T;--T)
    	{
    		scanf("%d",&n);
    		AC.Init();
    		for(int i=1;i<=n;++i)
    		{
    			scanf("%s",s);
    			AC.Insert(s);
    		}
    		AC.Build();
    		scanf("%s",s);
    		printf("%d
    ",AC.Query(s));
    	}
    	return 0;
    }
    
  • 相关阅读:
    启明星门户网站Portal发布V4.5,并兼论部分功能的实现
    修改SQL数据库dbo所有者
    iphone& android 开发指南 http://mobile.tutsplus.com
    启明星会议室预定系统V5.0.0.0版本说明
    启明星Portal企业内部网站V4.3版 附演示地址 http://demo.dotnetcms.org
    在winform程序里实现最小化隐藏到windows右下角
    【门户网站】启明星Portal系统里,关于天气预报调用的说明
    获取客户端经纬度坐标
    修改表名或者列名SQL
    ER图
  • 原文地址:https://www.cnblogs.com/hihocoder/p/12818314.html
Copyright © 2011-2022 走看看