通过数组构建trie树,还有一种链表构建的,下次更。
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
int trie[100000][26];
int fail[100000];
int cnt=0;
const int root=0;
int size[100000];
class node{
public:
int pos;
int len;
node(int pos,int len):pos(pos),len(len){
}
void disp(char *s)
{
printf("<%d,\"",this->pos);
for(int i=pos;i<pos+len;i++)
{
printf("%c",s[i]);
}
printf("\">");
}
};
void insert(char *s)
{
int len=strlen(s);
int p=root;
for(int i=0;i<=len-1;i++)
{
int next=s[i]-'a';
if(!trie[p][next])
{
trie[p][next]=++cnt;
}
p=trie[p][next];
}
size[p]=len;
}
void getfail()
{
queue<int> q;
for(int i=0;i<=25;i++)
{
if(trie[root][i])
{
q.push(trie[root][i]);
}
}
while(!q.empty())
{
int tmp=q.front();
q.pop();
for(int i=0;i<=25;i++)
{
if(trie[tmp][i])
{
fail[trie[tmp][i]]=trie[fail[tmp]][i];
q.push(trie[tmp][i]);
}
else
trie[tmp][i]=trie[fail[tmp]][i];
}
}
}
void query(char *s,vector<node>& q){
int len=strlen(s);
int p=root;
for(int i=0;i<=len-1;i++)
{
p=trie[p][s[i]-'a'];
for(int j=p;j;j=fail[j])
{
if(size[j])
{
q.push_back(node(i-size[j]+1,size[j]));
}
}
}
return ;
}
int main()
{
int n;
scanf("%d",&n);
for(int i=0;i<=n-1;i++)
{
char tmp[100];
scanf("%s",tmp);
insert(tmp);
}
getfail();
char m[10000];
scanf("%s",m);
vector<node> v;
query(m,v);
for(auto it=v.begin();it!=v.end();it++)
{
it->disp(m);
}
return 0;
}