Pagini recente » Cod sursa (job #2448128) | Cod sursa (job #1719111) | Cod sursa (job #2379895) | Cod sursa (job #1317486) | Cod sursa (job #2221216)
#include <queue>
#include <vector>
#include <string>
#include <fstream>
#include <memory>
#include <cstdlib>
#define NMAX 26
#define MAX_WORDS 100
using namespace std;
struct Tree
{
shared_ptr<Tree> child[NMAX];
shared_ptr<Tree> fail;
int counter;
vector<int>pattern;
Tree();
};
Tree::Tree()
{
counter = 0;
}
queue<shared_ptr<Tree>> Q;
shared_ptr<Tree> tree;
string s, stringToFind;
int n, k, i, solution[MAX_WORDS];
bool Insert(shared_ptr<Tree>& nod)
{
if (nod->child[stringToFind[k]-'a'] == 0)
{
Tree *t = new Tree;
nod->child[stringToFind[k]-'a'] = shared_ptr<Tree>(t);
}
++k;
if (stringToFind[k] == '\n')
{
nod->child[stringToFind[k-1]-'a']->pattern.push_back(i);
return true;
}
return Insert(nod->child[stringToFind[k-1]-'a']);
return true;
}
void Solution(shared_ptr<Tree> nod)
{
for (int j = 0; j < nod->pattern.size(); j++)
solution[nod->pattern[j]] += nod->counter;
for (int j = 0; j < NMAX; j++)
if (nod->child[j])
Solution(nod->child[j]);
}
int main()
{
Tree *t = new Tree;
tree = shared_ptr<Tree>(t);
shared_ptr<Tree> nod;
ifstream fin("ahocorasick.in");
fin >> s >> n;
s+="\n";
for (i = 0; i < n; i++)
{
fin >> stringToFind;
stringToFind+="\n";
nod = tree;
k = 0;
if (!Insert(nod))
return EXIT_FAILURE;
}
fin.close();
for (i = 0; i < NMAX; i++)
if (tree->child[i])
{
tree->child[i]->fail = tree;
Q.push(tree->child[i]);
}
while (!Q.empty())
{
shared_ptr<Tree> cNod = Q.front();
Q.pop();
for (i = 0; i < NMAX; i++)
{
if (!cNod->child[i]) continue;
Q.push(cNod->child[i]);
shared_ptr<Tree> cChild = cNod->child[i];
shared_ptr<Tree> cFail = cNod->fail;
while (!cFail->child[i]) cFail = cFail->fail;
if (!cFail->child[i]) cChild->fail = tree;
else cChild->fail = cFail->child[i];
for (int j = 0; j < cChild->fail->pattern.size(); j++)
cChild->pattern.push_back(cChild->fail->pattern[j]);
}
}
nod = tree;
k = 0;
for (k = 0; k < s.length(); k++)
{
while(nod != tree && nod->child[s[k]-'a'] == 0)
nod = nod->fail;
if(nod->child[s[k]-'a'] != 0)
nod = nod->child[s[k]-'a'];
nod->counter++;
}
Solution(tree);
ofstream fout("ahocorasick.out");
for(i = 0; i < n; i++)
fout << solution[i] << "\n";
fout.close();
return 0;
}