Pagini recente » Cod sursa (job #271031) | Cod sursa (job #1429656) | Cod sursa (job #1578035) | Cod sursa (job #1531099) | Cod sursa (job #2022670)
#include <vector>
#include <iostream>
#include <fstream>
#include <queue>
#include <cstring>
using namespace std;
ifstream in("ahocorasick.in");
ofstream out("ahocorasick.out");
const int ALPHALEN = 26, MAXN = 100, MAXLEN = 10000, MAXLENTEXT=1e6;
int n, ans[MAXN+1];
char text[MAXLENTEXT+1];
struct node
{
vector <int> output;
int index;
node* next[ALPHALEN+1];
node* fail;
node()
{
for(int i = 0; i < ALPHALEN; i++)
next[i] = NULL;
}
};
struct finiteAutomata
{
node* root;
int numStates;
finiteAutomata()
{
root = new node;
root->index = 0;
numStates = 0;
}
void addWord(node* &root, char* s, int k)
{
if(root == NULL)
{
root = new node;
numStates++;
root->index = numStates;
}
if(strlen(s) == 1)
{
root->output.push_back(k);
return;
}
addWord(root->next[s[1]-'a'],s+1,k);
}
void buildFailFunction()
{
queue <node*> Q;
for(int i = 0; i < ALPHALEN; i++)
if(root->next[i] != NULL)
{
root->next[i]->fail = root;
//printf("f(%d) = %d\n",root->next[i]->index,root->index);
Q.push(root->next[i]);
}
while(Q.empty() == false)
{
node* curr = Q.front();
Q.pop();
for(int i = 0; i < ALPHALEN; i++)
{
if(curr->next[i] != NULL)
{
Q.push(curr->next[i]);
node* state= curr->fail;
while(state != root && state->next[i] == NULL)
state = state->fail;
node *s, *fs;
s = curr->next[i];
fs = state->next[i];
if(fs == NULL)
{
s->fail = root;
}
else
{
s->fail = fs;
s->output.insert(s->output.begin(),fs->output.begin(),fs->output.end());
}
//printf("fail(%d) = %d\n",s->index,fs->index);
}
}
}
for(int i = 0; i < ALPHALEN; i++)
if(root->next[i] == NULL)
root->next[i] = root;
}
void matchText(char* text)
{
int textLen = strlen(text);
node* state = root;
for(int i = 0; i < textLen; i++)
{
char currChar = text[i];
while(state->next[currChar-'a'] == NULL)
state = state->fail;
state = state->next[currChar-'a'];
if(state->output.empty() == false)
{
for(int word: state->output)
ans[word]++;
}
}
}
void afis(node* root)
{
if(root == NULL)
return;
for(int word: root->output)
cout<<word<<endl;
for(int i = 0; i < ALPHALEN; i++)
afis(root->next[i]);
}
};
finiteAutomata T;
char buff[MAXLEN+1];
void citire()
{
in>>text;
in>>n;
for(int i = 1; i <= n; i++)
{
in>>buff;
T.addWord(T.root->next[buff[0]-'a'],buff,i);
}
}
int main()
{
citire();
T.buildFailFunction();
T.matchText(text);
//cout<<"Number of states is: "<<T.numStates<<endl;
for(int i = 1; i <= n; i++)
out<<ans[i]<<endl;
return 0;
}