Print how many keywords are contained in the description.
题意:求多少个字串 在 母串中出现过
例:
Sample Input
1 5 she he say shr her yasherhs
Sample Output
3
主要用了刘汝佳模板。。改了改,用的是UVA 1449 Dominating Patterns题的模板。。。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<map>
#include<queue>
#include<string>
using namespace std;
#define sigma_size 26
#define maxnode 500005 //节点个数
#define MAXS 10005
const int MAXN=1e6+10;
char p[MAXS][55];
char text[MAXN];
map<string,int> ms;
struct Trie//Trie模板
{
int f[maxnode];
int last[maxnode];
int cnt[MAXS]; //记录每个 出现的次数
int ch[maxnode][sigma_size];//maxnode表示节点个数,每个节点有26种情况,所以ch数组能表示所有情况
int val[maxnode]; //存节点的信息
int sz; //节点总个数
void clear(){
sz=1;
memset(ch[0],0,sizeof(ch[0]));
memset(cnt,0,sizeof(cnt));
ms.clear();
}//初始化
int idx(char c){ return c - 'a'; }
void insert(char *s, int v)
{
int u=0,n=strlen(s);
for(int i=0;i<n;i++){
int c=idx(s[i]);
if(!ch[u][c]){ //节点不存在
memset(ch[sz],0,sizeof(ch[sz]));
val[sz]=0;
ch[u][c]=sz++;
}
u=ch[u][c];//这样存就可以保证从每个节点,都能访问他的下一个节点了
}
val[u]=v;
ms[string(s)]=v;
}
void getFail()
{
queue<int> q;
f[0]=0;
for(int c=0;c<sigma_size;c++){
int u=ch[0][c];
if(u){f[u]=0; q.push(u); last[u]=0; }
}
while(!q.empty()){
int r=q.front(); q.pop();
for(int c=0;c<sigma_size;c++){
int u=ch[r][c];
if(!u) {ch[r][c]=ch[f[r]][c]; continue;}
q.push(u);
int v=f[r];
while(v && !ch[v][c] ) v=f[v];
f[u]=ch[v][c];
last[u]=val[f[u]]?f[u]:last[f[u]];
}
}
}
void find(char *t){
int n=strlen(t);
int j=0;
for(int i=0;i<n;i++){
int c=idx(t[i]);
j=ch[j][c];
if(val[j]) print(j);
else if(last[j]) print(last[j]);
}
}
void print(int j)//计算每个字符串 在 文本串中出现次数时的 print函数
{
if(j){
cnt[val[j]]++;
print(last[j]);
}
}
};
Trie node;
int main()
{
int t;
int i,j,k;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
node.clear();
for(i=1;i<=n;i++)
{
scanf("%s",p[i]);
node.insert(p[i],i);
}
node.getFail();
scanf("%s",text);
node.find(text);
int best=-1;
int sum=0;
for(i=1;i<=n;i++)
if(node.cnt[ms[string(p[i])]] > 0)
sum++;
printf("%d\n",sum);
}
return 0;
}