Pagini recente » Cod sursa (job #2495400) | Cod sursa (job #2384752) | Cod sursa (job #2497095) | Cod sursa (job #1059846) | Cod sursa (job #1451030)
#include <fstream>
#include <cstring>
using namespace std;
ifstream fin("ahocorasick.in");
ofstream fout("ahocorasick.out");
struct Trie
{
Trie * Son[26];
Trie * Fail;
int Index;
int Frequency;
Trie()
{
memset(Son,0, sizeof(Son));
Fail = 0;
Index = Frequency = 0;
}
};
const int NMax = 1000005;
const int LMax = 10005;
char String[NMax];
int Sol[NMax];
int N,K;
Trie * T = new Trie;
Trie * Q[LMax * LMax];
void Insert(Trie * Node, char * S,int Idx)
{
if(!isalpha(*S))
{
Node->Index = Idx;
return;
}
if(Node->Son[*S-'a']==0)
{
Node->Son[*S-'a'] = new Trie;
}
Insert(Node->Son[*S-'a'],S+1,Idx);
}
void Read()
{
fin>>String;
fin>>N;
for(int i = 1; i <= N; i++)
{
char S[10005];
fin>>S;
Insert(T,S,i);
}
}
void BFS()
{
T->Fail = T;
Q[1] = T;
K = 1;
for(int i = 1; i<=K; i++)
{
Trie * Node = Q[i];
for(int i = 0; i < 26 ; ++i)
{
Trie * Fiu = Node->Son[i];
if(!Fiu) continue;
Trie * Current_Fail = Node->Fail;
while(Current_Fail->Son[i]==0 && Current_Fail!=T)
Current_Fail = Current_Fail->Fail;
if(Current_Fail ==T && T->Son[i]==0)
Fiu->Fail = Current_Fail;
else
Fiu->Fail = Current_Fail->Son[i];
if(Fiu -> Fail == Fiu)
Fiu->Fail = T;
Q[++K] = Fiu;
}
}
T->Fail = 0;
}
void Parse()
{
Trie * Node = T;
for(int i = 0; String[i]; ++i)
{
int Ch = String[i] - 'a';
while(Node -> Son[Ch]==0 && Node != T)
Node = Node -> Fail;
if(Node->Son[Ch])
{
Node = Node->Son[Ch];
Node->Frequency++;
}
}
}
void AntiBFS()
{
for(int i = K; i > 0; i--)
{
Trie * Node = Q[i];
if(Node->Fail)
Node->Fail->Frequency += Node->Frequency;
Sol [Node->Index] = Node->Frequency;
}
}
void Print()
{
for(int i = 1; i<=N; ++i)
fout<<Sol[i]<<"\n";
}
int main()
{
Read();
BFS();
Parse();
AntiBFS();
Print();
return 0;
}