Pagini recente » Cod sursa (job #2320685) | Cod sursa (job #581975) | Cod sursa (job #3278013) | Cod sursa (job #317194) | Cod sursa (job #1839023)
#include <fstream>
#include <vector>
#include <iostream>
#include <queue>
using namespace std;
int n;
char text[1000000];
char s[10000];
struct Trie
{
Trie *sons[26],*back;
int count;
vector<Trie*> G;
Trie() {
for (int i = 0; i < 26; i++)
sons[i] = NULL;
back = NULL;
count = 0;
G.clear();
}
};
Trie *root = new Trie, *leafs[101];
Trie *addWord(Trie *T,char *c)
{
if (*c == 0)
return T;
int nxt = *c - 'a';
if (T->sons[nxt] == NULL)
T->sons[nxt] = new Trie;
return addWord(T->sons[nxt],c+1);
}
void bfs()
{
queue<Trie*> Q;
Q.push(root);
while (!Q.empty())
{
Trie *T = Q.front(); Q.pop();
for (int i = 0; i < 26; i++) // pentru fiecare fiu caut muchia fail
{
if (T->sons[i] == NULL) continue; // nu exista acest fiu
Trie *u = T->back; // pentru a calcula muchia fail pentru fiu ma folosesc de muchia fail a parintelui
while (u != NULL && u->sons[i] == NULL) // cat timp prefixul pentru parinte >= 1 si nu pot sa il fac prefix pentru fiu
u = u->back;
if (u == NULL) // daca nu am gasit prefix muchia de intoarcere va fi catre radacina
u = root;
else
u = u->sons[i];
T->sons[i]->back = u; // setam muchia fail pentru fiu
u->G.push_back(T->sons[i]);
Q.push(T->sons[i]);
}
}
}
void dfs(Trie *T)
{
for (int i = 0; i < T->G.size(); i++)
{
dfs(T->G[i]);
T->count += T->G[i]->count;
}
}
int main()
{
ifstream fin("ahocorasick.in");
ofstream fout("ahocorasick.out");
fin >> text;
fin >> n;
for (int i = 1; i <= n; i++)
{
fin >> s;
leafs[i] = addWord(root,s);
}
bfs();
Trie *T = root;
for (char *c = text; *c; c++)
{
int nxt = *c - 'a';
while (T != NULL && T->sons[nxt] == NULL)
T = T->back;
if (T == NULL)
T = root;
else
T = T->sons[nxt];
T->count++;
}
dfs(root);
for (int i = 1; i <= n; i++)
fout << leafs[i]->count << "\n";
}