HDU3065 病毒侵袭持续中

来源:互联网 发布:linux vsftpd 编辑:程序博客网 时间:2024/05/03 10:43

题意: 一个大的字符串中找出一些小的字符串是否存在其中(其中小的字符串都是大写字母,大字符串里的字符则所有字符都可能)


注意:多数据处理,注意初始化


#include<iostream>#include<queue>using namespace std;const int kind=26;struct my{int index;struct my *fail,*next[kind];my(){index=0;fail=NULL;memset(next,NULL,sizeof(next));}};char go[1111][55];char s[2222222];void insert(my *root,char *s,int n){my *cur=root;int i=0;while (s[i]){int index=s[i++]-'A';if (!cur->next[index]) cur->next[index] = new my;cur=cur->next[index];}cur->index = n;}void build_fail(my *root){queue<my*> q;q.push(root);while (!q.empty()){my *cur=q.front();q.pop();for (int i=0;i<kind;i++) if (cur->next[i]){q.push(cur->next[i]);if (cur==root){cur->next[i]->fail = root;continue;}my *temp=cur->fail;while (temp){if (temp->next[i]) {cur->next[i]->fail = temp->next[i];break;}temp=temp->fail;}if (!temp) cur->next[i]->fail = root;}}}int ans[1111];void query(my *root){int i=0;my *cur=root;while (s[i])  if (s[i]>='A' && s[i]<='Z'){int index=s[i++]-'A';//cout<<i<<' '<<s[i-1]<<' '<<root->next[index]<<endl;while (!cur->next[index] && cur!=root) cur = cur->fail;if (cur->next[index]) cur=cur->next[index];else cur = root;my *temp=cur;while (temp!=root){if (temp->index) ans[temp->index]++;temp = temp->fail;}}else cur=root,i++;}int main(){freopen("in","r",stdin);int n;while (cin>>n){my *root=new my;for (int i=1;i<=n;i++) scanf("%s",go[i]),insert(root,go[i],i);build_fail(root);scanf("%s",s);query(root);for (int i=1;i<=n;i++) if (ans[i]){printf("%s: %d\n",go[i],ans[i]);}memset(ans,0,sizeof(ans));}}


0 0
原创粉丝点击