ac自动机--------trie图优化-搜索关键词

给定 nn 个长度不超过 5050 的由小写英文字母组成的单词,以及一篇长为 mm 的文章。
请问,有多少个单词在文章中出现了。
输入格式
第一行包含整数 TT,表示共有 TT 组测试数据。
对于每组数据,第一行一个整数 nn,接下去 nn 行表示 nn 个单词,最后一行输入一个字符串,表示文章。
输出格式
对于每组数据,输出一个占一行的整数,表示有多少个单词在文章中出现。
数据范围
1≤n≤1041≤n≤104,

1≤m≤1061≤m≤106
输入样例:
1
5
she
he
say
shr
her
yasherhs

输出样例:
3

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=10010,S=55,M=1000010;
int n;
int tr[N*S][26],cnt[N*S],idx;
char str[M];
int q[N*S],ne[N*S];
void insert(){
 int p=0;
 for(int i=0;str[i];i++){
  int t=str[i]-'a';
  if(!tr[p][t])   tr[p][t]=++idx;
  p=tr[p][t];
 }
 cnt[p]++;
}
void build(){
 int hh=0,tt=-1;
 for(int i=0;i<26;i++)
    if(tr[0][i])
     q[++tt]=tr[0][i];
 while(hh<=tt){
  int t=q[hh++];
  for(int i=0;i<26;i++){
   int c=tr[t][i];
   if(!c)   continue;
   int j=ne[t];
   while(j&& !tr[j][i])   j=ne[j];
   if(tr[j][i])    j=tr[j][i];
   ne[c]=j;
   q[++tt]=c;
  }
 }
}
int main(){
 int T;
 scanf("%d",&T);
 while(T--){
  memset(tr,0,sizeof tr);
  memset(cnt,0,sizeof cnt);
  memset(ne,0,sizeof ne);
  idx=0;
  scanf("%d",&n);
  for(int i=0;i<n;i++){
   scanf("%s",str);
   insert();
  }
  build();
  scanf("%s",str);
  int res=0;
  for(int i=0,j=0;str[i];i++){
   int t=str[i]-'a';
   while(j && !tr[j][t])    j=ne[j];
   if(tr[j][t])   j=tr[j][t];
   int p=j;
   while(p){
    res+=cnt[p];
    cnt[p]=0;
    p=ne[p];
   }
  }
  printf("%d\n",res);
 }
 return 0;
}

trie图优化

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=10010,S=55,M=1000010;
int n;
int tr[N*S][26],cnt[N*S],idx;
char str[M];
int q[N*S],ne[N*S];
void insert(){
 int p=0;
 for(int i=0;str[i];i++){
  int t=str[i]-'a';
  if(!tr[p][t])   tr[p][t]=++idx;
  p=tr[p][t];
 }
 cnt[p]++;
}
void build(){
 int hh=0,tt=-1;
 for(int i=0;i<26;i++)
    if(tr[0][i])
     q[++tt]=tr[0][i];
 while(hh<=tt){
  int t=q[hh++];
  for(int i=0;i<26;i++){
   int p=tr[t][i];
   if(!p)    tr[t][i]=tr[ne[t]][i];
   else{
    ne[p]=tr[ne[t]][i];
    q[++tt]=p;
   }
  }
 }
}
int main(){
 int T;
 scanf("%d",&T);
 while(T--){
  memset(tr,0,sizeof tr);
  memset(cnt,0,sizeof cnt);
  memset(ne,0,sizeof ne);
  idx=0;
  scanf("%d",&n);
  for(int i=0;i<n;i++){
   scanf("%s",str);
   insert();
  }
  build();
  scanf("%s",str);
  int res=0;
  for(int i=0,j=0;str[i];i++){
   int t=str[i]-'a';
      j=tr[j][t];
   int p=j;
   while(p){
    res+=cnt[p];
    cnt[p]=0;
    p=ne[p];
   }
  }
  printf("%d\n",res);
 }
 return 0;
}
发布了37 篇原创文章 · 获赞 28 · 访问量 3830

猜你喜欢

转载自blog.csdn.net/qq_45772483/article/details/104397330