hdu 2222 Keywords Search
来源:互联网 发布:家 医疗软件 编辑:程序博客网 时间:2024/06/06 18:18
题目链接:hdu 2222 Keyworld Serach
字符串的多模式匹配
题意:给你n个单词和一个主串,让你求有多少单词在主串中出现
#include<iostream>#include<queue>#include<cstring>#include<cstdio>#define maxn 1000005using namespace std;int head,tail;//队列头尾指针struct node{ node *fail; //fail指针表指向与与该元素相同的节点或根节点 node *next[26];//26个小写字母 int count;//记录每一个单词的末尾 node() //结构体重载 { fail =NULL; memset(next,0,sizeof(next)); count = 0 ; }}*q[maxn];node *root;void insert(char s[])//建立字典树,这里就是26叉树{ node *p=root; int len =strlen(s); for(int i=0;i<len;i++) { int id=s[i]-'a'; if(p->next[id]==NULL) p->next[id]=new node();//若根节点下当前字符没有出现过,新建里一个当前字符的节点 p=p->next[id];//p指向当前节点 } p->count++;//单词末尾的次数加1,代表右边出现过几个最后一个字符为末尾元素的子串}void build_ac()//建立fail指针{ node *p,*temp=NULL; q[tail++]=root;//根节点先入队 while(head!=tail) //队列不为空时 { p=q[head++];//出队 for(int i=0;i<26;i++)//26叉树,寻找单词的首字母 { if(p->next[i])//不为空就表示该字符存在 { if(p==root)//当孩子的父亲为根节点,也就是该字符位于第一层 p->next[i]->fail=root; //直接将失败指针指向根节点 else { temp = p->fail;//否则先记录当前节点的失败指针 while(temp!=NULL)//当指向为空时,跳出,这里有个误区,不能在temp等于root时跳出,因为可能根节点的儿子中存在与当前节点儿子相同的字符 { if(temp->next[i]) //如果当前节点指向的失败指针的儿子与当前节点的儿子相同 { p->next[i]->fail=temp->next[i];//将当前节点的儿子的失败指针指向它 break; } temp=temp->fail;//否则一直找与当前节点相同的元素 } if(temp==NULL) p->next[i]->fail=root;//找不到,则直接把当前节点的儿子指向根节点 } q[tail++]=p->next[i];//将当前节点的儿子入队以便在下一层完成他儿子的失败指针 } } }}/*在串里找单词实际上是一个一个找,找到一个字符一样,加上他的count值,然后通过失败指针返回根节点,所以要用一个temp来这样做,p的指针始终通过主串来改变,找到一个字符相等,p不变,temp变,再比较p的儿子与主串中下一个字符,重复以上操作*/int query(char s[])//查找有几个单词出现{ node *p=root,*temp; int len = strlen(s); int res=0; for(int i=0;i<len;i++) { int id =s[i]-'a'; while(p->next[id]==NULL&&p!=root) p=p->fail;//如果p位于字典树一边的末尾,跳转到与p儿子相同元素的,若没有跳转到根节点 p=p->next[id];//p指向当前元素 if(p==NULL) p=root;//如果这样的字符不存在,则指向根节点 temp = p;//p不能改变,否则下一个字符就无法比较 while(temp!=root&&temp->count!=-1)//终点就是回到根而且再找的过程中找到一个必须标记为找过,否则会重复加 { res+=temp->count;//加上当前字符的count值 temp->count=-1; //标记为访问过 temp=temp->fail; //不断找同的元素。直到回到根 } } return res;}int main(){ int t,n; char s[maxn]; scanf("%d",&t); while(t--) { scanf("%d",&n); root = new node(); head=tail=0; while(n--) { scanf("%s",s); insert(s); } build_ac(); scanf("%s",s); int res = query(s); printf("%d\n",res); } return 0;}
0 0
- hdu 2222 Keywords Search
- hdu 2222 Keywords Search
- HDU-2222 Keywords Search
- hdu 2222 Keywords Search
- Hdu 2222 Keywords Search
- hdu 2222-Keywords Search
- hdu 2222 Keywords Search
- HDU 2222 Keywords Search
- HDU 2222 Keywords Search
- Hdu 2222 Keywords Search
- HDU 2222 Keywords Search
- HDU 2222 Keywords Search
- HDU 2222 Keywords Search
- hdu 2222 Keywords Search
- HDU 2222 Keywords Search
- hdu 2222 Keywords Search
- HDU 2222 Keywords Search
- HDU - 2222 Keywords Search
- gdb反向调试命令
- iOS项目开发实战——开发基于Handoff的App(Swift)
- 【已解决】Activity MainActivity has leaked window PhoneWindow$DecorView@ that was originally added here
- 2015.11.10 asn1学习笔记
- VS2010 控件集总介绍
- hdu 2222 Keywords Search
- [kuangbin带你飞]专题一 简单搜索H - Pots(POJ 3414)
- 【AC自动机】HDU2222Keywords Search
- PS水印字体的制作
- VC中CStatic设置文字、字体、颜色和OnCtlColor的使用
- Struts2 在IDEA<s:datetimepicker/>的问题
- react native image resizeMode理解
- 杭电2896题 AC自动机模板题
- A. Vitaly and Night