Pagini recente » Cod sursa (job #260561) | Borderou de evaluare (job #367084) | Cod sursa (job #149470) | Cod sursa (job #380290) | Cod sursa (job #2442904)
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("ahocorasick.in");
ofstream fout("ahocorasick.out");
const int LMax = 10002;
char S[1000005], W[LMax + 5];
int N, Sol[105];
struct Trie
{
int val; vector <int> List;
Trie * Son[28], * Match;
Trie()
{
val = 0; Match = NULL;
for(int i = 0; i < 28; i++)
Son[i] = NULL;
}
};
Trie * Root = new Trie;
vector <Trie*> V;
void Add(Trie * & Nod, char * T, int i)
{
if(*T == 0)
{
Nod -> List.push_back(i);
return;
}
char c = *T - 'a';
if(Nod -> Son[c] == NULL)
Nod -> Son[c] = new Trie;
Add(Nod -> Son[c], T + 1, i);
}
void BFS()
{
V.push_back(Root);
Root -> Match = Root;
for(int i = 0; i < V.size(); i++)
{
Trie * Tata = V[i];
for(int c = 0; c < 28; c++)
{
Trie * Nod = Tata -> Son[c];
if(!Nod) continue;
Trie * Finder = Tata -> Match;
while(Finder -> Son[c] == NULL && Finder != Root)
Finder = Finder -> Match;
if(Finder -> Son[c] == NULL)
Nod -> Match = Root;
else
Nod -> Match = Finder -> Son[c];
if(Nod -> Match == Nod)
Nod -> Match = Root;
V.push_back(Nod);
}
}
}
void Solve()
{
Trie * Nod = Root;
for(int i = 0; S[i]; i++)
{
char c = S[i] - 'a';
while(Nod -> Son[c] == NULL && Nod != Root)
Nod = Nod -> Match;
if(Nod -> Son[c])
{
Nod = Nod -> Son[c];
Nod -> val++;
}
}
}
void Spread()
{
while(!V.empty())
{
Trie * Nod = V.back(); V.pop_back();
for(auto j : Nod -> List)
Sol[j] = Nod -> val;
Nod -> Match -> val += Nod -> val;
}
}
int main()
{
fin >> S >> N;
for(int i = 1; i <= N; i++)
fin >> W, Add(Root, W, i);
BFS(); Solve(); Spread();
for(int i = 1; i <= N; i++)
fout << Sol[i] << '\n';
fin.close();
fout.close();
return 0;
}