Pagini recente » Cod sursa (job #2863418) | Istoria paginii runda/pregatire_lot_1/clasament | Cod sursa (job #1008934) | Cod sursa (job #2934498) | Cod sursa (job #1994271)
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <windows.h>
using namespace std;
ifstream fin("ahocorasick.in");
ofstream fout("ahocorasick.out");
const int NLIM = 1e6 + 10;
int gi;
vector< int > graph[NLIM];
int parent[NLIM];
int suff[NLIM];
int nodnr = 1;
char nodc[NLIM];
int depth[NLIM];
int wend[NLIM];
int res[NLIM];
int N;
string str;
string s;
void addTrie( int nod, int idx )
{
// for( int i = 0; i < depth[nod]; ++i )
//cout << " ";
//cout << nod << " " << nodc[nod] << " " << idx << " ";
int found = 0;
for( int j = 0; j < graph[nod].size() && !found; ++j )
{
int nnod = graph[nod][j];
if( nodc[nnod] == s[idx] )
{
found = nnod;
}
}
//cout << found << " * ";
if( found )
{
// last
if( idx == s.size() - 1 )
{
wend[found] = gi;
//cout << " |wendf| " << found << " " << wend[found] << " ";
}
else
{
addTrie( found, idx + 1 );
}
}
if( !found )
{
// cout << " |add| ";
++nodnr;
graph[nod].push_back( nodnr );
depth[nodnr] = depth[nod] + 1;
nodc[nodnr] = s[idx];
parent[nodnr] = nod;
// cout << nodnr << " ";
if( idx == s.size() - 1 )
{
wend[nodnr] = gi;
//cout << " |wendn| " << nodnr << " " << wend[nodnr] << " ";
}
else
{
addTrie( nodnr, idx + 1 );
}
}
//cout << "\n";
}
void findSuff( int nod )
{
// cout << " | ";
//cout << nod << " " << nodc[nod] << "\n";
int tnod = parent[nod];
bool f = 0;
while( tnod != -1 && !f )
{
for( int j = 0; j < graph[tnod].size(); ++j )
{
int nnod = graph[tnod][j];
if( nodc[nnod] == nodc[nod] && nod != nnod )
{
suff[nod] = nnod;
return;
}
}
if( !suff[tnod] )
{
//Sleep( 10000 );
findSuff( tnod );
}
tnod = suff[tnod];
//cout << tnod << " ";
}
//cout << "\n";
suff[nod] = 1;
}
void bfs( int nod )
{
//cout << nod << "\n";
if( nod != 1 && !suff[nod] )
{
findSuff( nod );
}
for( int j = 0; j < graph[nod].size(); ++j )
{
int nnod = graph[nod][j];
bfs( nnod );
}
}
int dirNode( int nod, char c )
{
for( int j = 0; j < graph[nod].size(); ++j )
{
int nnod = graph[nod][j];
if( nodc[nnod] == c )
{
return nnod;
}
}
return 0;
}
int nextNode( int nod, char c )
{
while( nod != -1 )
{
int dirn = dirNode( nod, c );
if( dirn )
{
return dirn;
}
nod = suff[nod];
}
return 1;
}
int main()
{
parent[1] = -1;
suff[1] = -1;
depth[1] = 0;
nodc[1] = '-';
fin >> str;
fin >> N;
for( gi = 1; gi <= N; ++gi )
{
fin >> s;
//cout << s << "\n";
addTrie( 1, 0 );
}
bfs( 1 );
/*/
for( int i = 1; i <= nodnr; ++i )
{
cout << i << " " << nodc[i] << ": ";
for( int j = 0; j < graph[i].size(); ++j )
{
cout << nodc[graph[i][j]] << " ";
}
cout << "\n";
cout << suff[i] << " " << nodc[suff[i]] << "\n";
}
//*/
int hnod = 1;
//cout << hnod << "\n";
for( gi = 0; gi < str.size(); ++gi )
{
// find next node
hnod = nextNode( hnod, str[gi] );
// results:
int tnod = hnod;
//cout << gi << ": ";
while( tnod != 1 )
{
if( wend[tnod] )
++res[wend[tnod]];
tnod = suff[tnod];
}
//cout << "\n";
}
for( int i = 1; i <= N; ++i )
{
fout << res[i] << "\n";
}
return 0;
}