Pagini recente » Cod sursa (job #948286) | Cod sursa (job #1590716) | Cod sursa (job #1108330) | Istoria paginii runda/concurs_nou-andrei | Cod sursa (job #1422656)
#include <fstream>
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;
class aho_corasick
{
public:
void add_word(string s)
{
wordcount++;
int nod=rad,lim=s.length();
for(int i=0;i<lim;i++)
{
if(v[nod].delta[cod(s[i])]==nil)
{
int a=newnode();
v[nod].delta[cod(s[i])]=a;
}
nod=v[nod].delta[cod(s[i])];
}
v[nod].indcuv.push_back(wordcount-1);
}
void compute_delta_pi()
{
v[rad].pi=rad;
q.push_back(rad);
for(int i=0;i<q.size();i++)
{
int nod=q[i];
for(int j=0;j<sigma;j++)
{
int k=v[nod].pi;
while(k!=rad && v[k].delta[j]==nil) k=v[k].pi;
if(v[k].delta[j]!=nil && k!=nod) k=v[k].delta[j];
if(v[nod].delta[j]!=nil)
{
v[v[nod].delta[j]].pi=k;
q.push_back(v[nod].delta[j]);
}
else v[nod].delta[j]=k;
}
}
reverse(q.begin(),q.end());
}
vector<int> getfreq(string s)
{
vector<int> freq=vector<int>(wordcount,0);
int lim=s.length(),nod=rad;
for(int i=0;i<lim;i++)
{
nod=v[nod].delta[cod(s[i])];
v[nod].nr++;
}
for(vector<int>::iterator it=q.begin();it!=q.end();it++)
if(*it!=rad) v[v[*it].pi].nr+=v[*it].nr;
for(int i=0;i<v.size();i++)
if(i!=rad) for(vector<int>::iterator it=v[i].indcuv.begin();it!=v[i].indcuv.end();it++) freq[*it]+=v[i].nr;
return freq;
}
private:
static const int nil=-1,sigma=26;
struct node
{
int nr,pi;
vector<int> indcuv,delta;
node()
{
nr=0;
indcuv=vector<int>();
delta=vector<int>(sigma,nil);
}
};
vector<node> v=vector<node>(1,node());
vector<int> q;
int wordcount=0,rad=0;
int newnode()
{
v.push_back(node());
return v.size()-1;
}
int cod(char c)
{
return c-'a';
}
};
int main()
{
ifstream f("ahocorasick.in");
ofstream g("ahocorasick.out");
int n;
string s,s1;
aho_corasick v;
f>>s>>n;
for(int i=1;i<=n;i++)
{
f>>s1;
v.add_word(s1);
}
v.compute_delta_pi();
vector<int> freq=v.getfreq(s);
for(int i=0;i<n;i++) g<<freq[i]<<'\n';
g.close();g.close();
return 0;
}