AC自动机应用 多模式匹配 多个单词在文章中出现的次数-C语言实现

来源:互联网 发布:文件加密解密算法 编辑:程序博客网 时间:2024/05/29 15:53
/*AC自动机应用 多模式匹配 多个单词在文章中出现的次数*/#define N 500char str[1000],keyword[51];int head,tail;// 表示字典树的一个节点 struct node{ node * fail;node * next[26]; int count;node(){fail = NULL;count = 0;for(int i=0;i<26;i++)next[i] = NULL;}} * q[N]; // q,用来逐层访问时的队列结构 node * root;void insert(char * str){int index,i; node * p = root;  // p代表当前的节点,开始为根节点int len = strlen(str);for(i=0;i<len;i++){index = str[i] - 'a';if( p->next[index] == NULL)p->next[index] = new node();p = p->next[index]; }p->count++; // 单词的结束节点count不为0,单词组中有多个相同单词,count>1}// 设置失败指针 void build_ac( ){ q[tail++] = root; //入队while(head!=tail){node *p = q[head++];node *temp = NULL;for(int i=0;i<26;i++){ // 处理子节点if(p->next[i]!=NULL){if(p==root){p->next[i]->fail = root;}else{temp = p->fail; // 父节点的fail,沿着fail找,直到找到匹配或者到达根 while(temp!=NULL){ // 中间节点 if(temp->next[i]!=NULL){ // 匹配 p->next[i]->fail = temp->next[i];break;}temp = temp ->fail;}if(temp == NULL){p->next[i]->fail = root;}}q[tail++] = p->next[i];} }} }int query(char str[]){int index,len,result;node * p = root;result = 0;len = strlen(str);for(int i=0;i<len;i++){index = str[i]-'a';while(p->next[index]==NULL&&p!=root) // 所有可能匹配的节点 p = p->fail;p = p->next[index]; // 状态转移 if (p==NULL) //  表示从root转移过来p = root;node * temp = p;// 判断是否是结束单词 while(temp!=root && temp->count!=-1 ){ //&& temp->count!=0result += temp->count;temp->count = -1; // 单词已经出现了,不再计数 temp = temp->fail; // 还有可能匹配的单词,其他的前缀为现在的后缀 }  }return result;}int main(){int ncase,num;ncase=1;strcpy(str,"abcdabc");while(ncase--){head = tail = 0;root = new node;char a[]="abc";insert(a);char b[]="bcd";insert(b);char c[]="bc";insert(c);build_ac( );cout<<query(str)<<endl;}return 0;} 

0 0
原创粉丝点击