【练习05】 AC自动机 1001 病毒侵袭

来源:互联网 发布:网络设计师 编辑:程序博客网 时间:2024/06/05 07:04

算法思路:AC自动机。

要点:

1.val存储病毒的编号;

2.find函数中当找到一个模板后,应该顺着失配边往回走,由last数组递归判断是否还有其他的子模板能够匹配,所有找到的模板的val值保存到数组save中。

3.对save数组进行sort排序,注意输出格式,依次打印病毒编号。

4.题中要求是“可见字符”,在不超内存的情况下,sigma_size最好开到127。

//模板开始#include <string>   #include <vector>   #include <algorithm>   #include <iostream>   #include <sstream>   #include <fstream>   #include <map>   #include <set>   #include <cstdio>   #include <cmath>   #include <cstdlib>   #include <ctime>#include <iomanip>#include <string.h>#include <queue>#define SZ(x) (int(x.size()))using namespace std;int toInt(string s){istringstream sin(s); int t; sin>>t; return t;}template<class T> string toString(T x){ostringstream sout; sout<<x; return sout.str();}typedef long long int64;int64 toInt64(string s){istringstream sin(s); int64 t; sin>>t;return t;}template<class T> T gcd(T a, T b){ if(a<0) return gcd(-a, b);if(b<0) return gcd(a, -b);return (b == 0)? a : gcd(b, a % b);}//模板结束(通用部分)#define ifs cin#define maxnode 100005#define sigma_size 127int save[maxnode];int cnt;struct Trie{int ch[maxnode][sigma_size];int val[maxnode];int sz;int f[maxnode];int last[maxnode];Trie(){sz = 1;memset(ch[0], 0, sizeof(ch[0]));}int idx(char c){return (int)c;}void insert(char* s, int v){int u = 0, n = strlen(s);for(int i = 0; i < n; i++){int c = idx(s[i]);if(!ch[u][c]){memset(ch[sz], 0, sizeof(ch[sz]));val[sz] = 0;ch[u][c] = sz++;}u = ch[u][c];}val[u] = v;}//int search(char* s, int n)//{//int u = 0;//int flag = 1;//for(int i = 0; i < n; i++)//{//int c = idx(s[i]);//if(ch[u][c] == 0)//{//flag = 0;//break;//}//u = ch[u][c];//}//if(flag && val[u])//{//return 1;//}//else//{//return 0;//}//}void getFail(){queue<int> q;f[0] = 0;for(int c = 0; c < sigma_size; c++){int u = ch[0][c];if(u){f[u] = 0;q.push(u);last[u] = 0;}while(!q.empty()){int r = q.front();q.pop();for(int c = 0; c < sigma_size; c++){int u = ch[r][c];if(!u){continue;}q.push(u);int v = f[r];while(v && !ch[v][c]){v = f[v];}f[u] = ch[v][c];last[u] = val[f[u]] ? f[u] : last[f[u]];}}}}void save_all(int j){if(j){save_all(last[j]);save[cnt++] = val[j];}}void find(char* T){int n = strlen(T);int j = 0; for(int i = 0; i < n; i++){int c = idx(T[i]);while(j && !ch[j][c]) {j = f[j];}j = ch[j][c];if(val[j]){save_all(j);}else{if(last[j]){save_all(last[j]);}}}}};Trie t;char a[505][205];char b[10005];int jishu;//【练习05】 AC自动机 1001 病毒侵袭int main(){//ifstream ifs("shuju.txt", ios::in);int n;while(ifs>>n){for(int i = 1; i <= n; i++){//ifs>>a[i];scanf("%s", &a[i]);t.insert(a[i], i);}t.getFail();ifs>>n;jishu = 0;for(int i = 1; i <= n; i++){//ifs>>b;scanf("%s", &b);cnt = 0;memset(save, 0, sizeof(save));t.find(b);if(!save[0]){continue;}else{jishu++;}sort(save, save + cnt);cout<<"web "<<i<<":";for(int j = 0; j < cnt; j++){cout<<" "<<save[j];}cout<<endl;}cout<<"total: "<<jishu<<endl;}return 0;}


原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 孕晚期脸过敏怎么办 吃芒果脸过敏怎么办 脸上老反复过敏怎么办 用什么都过敏怎么办 脸上起过敏湿疹怎么办 脸上发湿疹过敏怎么办 感冒流鼻涕有痰怎么办 咳嗽流清水鼻涕怎么办 脸最近老是过敏怎么办 鼻炎脸特别疼怎么办 宝宝感冒一直流鼻涕怎么办 经常过敏的体质怎么办 一边鼻子堵了怎么办 鼻炎流清水鼻涕怎么办 鼻子总感觉堵塞怎么办 半边鼻子不通气怎么办 鼻炎感冒了鼻塞怎么办 左边鼻子不通气怎么办 婴儿鼻塞不通气怎么办 过敏性鼻炎一直打喷嚏怎么办 一只鼻子流鼻涕怎么办 一个鼻子不通气怎么办 夏天鼻子堵了怎么办 做完鼻子感冒了怎么办 鼻子不通流鼻涕打喷嚏怎么办 一岁半宝宝流鼻涕鼻塞怎么办 没有感昌流鼻涕怎么办 婴儿感冒咳嗽流鼻涕怎么办 小孩经常流鼻子怎么办 5岁宝宝流鼻涕怎么办 小孩鼻涕一直流怎么办 二岁宝宝流鼻涕怎么办 小婴儿有点鼻塞怎么办 宝宝流鼻涕总不好怎么办 孩子鼻炎睡不好怎么办 鼻炎清鼻涕不止怎么办 宝宝持续低烧流鼻涕怎么办 孩子鼻塞不通气怎么办 2月婴儿感冒怎么办 长期流黄鼻涕怎么办 孩子流清水鼻涕怎么办