Pagini recente » Cod sursa (job #2171295) | Cod sursa (job #2173725) | Cod sursa (job #1588487) | Cod sursa (job #656196) | Cod sursa (job #2221226)
#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'])
{
Tree *t = new (std::nothrow) Tree;
if (!t)
return false;
nod->child[stringToFind[k]-'a'] = shared_ptr<Tree>(t);
}
++k;
if (k < stringToFind.length())
{
nod->child[stringToFind[k-1]-'a']->pattern.push_back(i);
return true;
}
return Insert(nod->child[stringToFind[k-1]-'a']);
}
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 (std::nothrow) Tree;
if (!t)
return EXIT_FAILURE;
tree = shared_ptr<Tree>(t);
shared_ptr<Tree> nod;
ifstream fin("ahocorasick.in");
fin >> 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 != tree && !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;
}