Pagini recente » Cod sursa (job #3261291) | Cod sursa (job #1333473) | Cod sursa (job #2354884) | Cod sursa (job #1362167) | Cod sursa (job #865134)
Cod sursa(job #865134)
#include <string>
#include <cstring>
#include <vector>
#include <fstream>
#include <queue>
class Matcher {
struct Node {
const static int SIGMA = 26;
Node* g[SIGMA];
Node* f;
std::vector< int > o;
Node() {
memset(g,0,sizeof(g));
}
};
Node * r;
std::vector <std::string> dict;
public:
Matcher(std::vector <std::string> & dict) {
this->r = new Node();
this->dict = dict;
for(int i=0;i<(int)dict.size();++i) {
Node * t = r;
for(int j=0;j<(int)dict[i].size();++j) {
if(t->g[ dict[i][j] - 'a' ] == NULL) {
t->g[ dict[i][j] - 'a' ] = new Node();
}
t = t->g[ dict[i][j] - 'a' ];
}
t->o.push_back( i );
}
for(int i=0;i<Node::SIGMA;++i)
if(r->g[i] == NULL)
r->g[i] = r;
std::queue<Node*> Q;
this->r->f = NULL;
for(int i=0;i<Node::SIGMA;++i) {
if(r->g[i] != r) {
Q.push(r->g[i]);
r->g[i]->f = r;
}
}
while(!Q.empty()) {
Node * t = Q.front();
Q.pop();
for(int i=0;i<Node::SIGMA;++i) {
if(t->g[i] != NULL) {
Node* tmp = t->f;
while(tmp->g[i] == NULL)
tmp = tmp->f;
tmp = tmp->g[i];
t->g[i]->f = tmp;
t->g[i]->o.insert(t->g[i]->o.end(),tmp->o.begin(),tmp->o.end());
Q.push(t->g[i]);
}
}
}
}
bool match(std::string & str,std::vector<int> &res) {
res = std::vector<int>(dict.size(),0);
Node *t = r;
for(int i=0;i<(int)str.size();++i) {
while(t->g[str[i] - 'a'] == NULL)
t = t->f;
t = t->g[str[i] - 'a'];
for(int j=0;j<(int)t->o.size();++j) {
res[ t->o[j] ] ++;
}
}
return res.size() > 0;
}
};
int main()
{
std::ifstream fin("ahocorasick.in");
std::ofstream fout("ahocorasick.out");
std::string A; fin >> A;
int M; fin >> M;
std::vector< std::string > dict;
while(M--)
{
std::string tmp; fin >> tmp; dict.push_back(tmp);
}
std::vector<int> res;
if(Matcher(dict).match(A,res))
{
for(int i=0;i<(int)res.size();++i) {
fout<<res[i]<<std::endl;
}
}
return 0;
}