模板:
struct Ac_Automation { int ch[MAXNNODE][SIGMA_SIZE]; int val[MAXNNODE]; int fail[MAXNNODE],last[MAXNNODE]; bool symbol[MAXNNODE]; int sz; Ac_Automation() {sz = 1;memset(ch[0],0,sizeof(ch[0]));symbol[0] = false;} int idx(char c) { return c - 'a'; } void insert(char * s) { 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])); symbol[sz] = false; ch[u][c] = sz++; } u = ch[u][c]; } symbol[u] = true;//最后的叶子节点给与信息v } //建立字典树 void get_fail() { queue<int>q; fail[0] = 0; for (int c = 0 ; c < SIGMA_SIZE ; c++) { int u = ch[0][c]; if (u) { fail[u] = 0; q.push(u); last[u] = 0; } } while (!q.empty()) { int r = q.front();q.pop(); if (symbol[fail[r]]) symbol[r] = true; for (int c = 0 ; c < SIGMA_SIZE ; c++) { int u = ch[r][c]; if (u == 0) { ch[r][c] = ch[fail[r]][c]; continue; } q.push(u); int v = fail[r]; while (v && !ch[v][c]) v = fail[v]; fail[u] = ch[v][c]; last[u] = val[fail[u]] ? fail[u] : last[fail[u]]; } } } void print(int j) { if (j) { // printf("%d\n",val[j]); // cnt[val[j]]++; print(last[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]) print(j); else if (last[j]) print(last[j]);//print是功能函数 } } void init() { sz = 1; memset(ch[0],0,sizeof(ch[0])); symbol[0] = false; } Matrix build_mat() { Matrix ret = Matrix(sz + 1); for (int i = 0 ; i < sz ; i++) for (int j = 0 ; j < SIGMA_SIZE ; j++) if (symbol[i] == false && !symbol[ch[i][j]]) ret.mat[i][ch[i][j]]++; for (int i = 0 ; i <= sz ; i++) ret.mat[i][sz] = 1; return ret; } }src;
HDU 2222 Keywords Search
找出主串中有多少个模式串出现
#include <map> #include <set> #include <list> #include <cmath> #include <ctime> #include <deque> #include <stack> #include <queue> #include <cctype> #include <cstdio> #include <string> #include <vector> #include <climits> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> #define LL long long #define PI 3.1415926535897932626 using namespace std; int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);} int ans; const int MAXNNODE = 500010; const int SIGMA_SIZE = 26; struct Ac_Automation { int ch[MAXNNODE][SIGMA_SIZE]; int val[MAXNNODE]; int cnt[MAXNNODE]; int sz; Ac_Automation() {sz = 1;memset(ch[0],0,sizeof(ch[0]));} int idx(char c) {return c - 'a';} 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]; } cnt[u]++; val[u] = v;//最后的叶子节点给与信息v } //建立字典树 int fail[MAXNNODE],last[MAXNNODE]; int get_fail() { queue<int>q; fail[0] = 0; for (int c = 0 ; c < SIGMA_SIZE ; c++) { int u = ch[0][c]; if (u) { fail[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 == 0) { ch[r][c] = ch[fail[r]][c]; continue; } q.push(u); int v = fail[r]; while (v && !ch[v][c]) v = fail[v]; fail[u] = ch[v][c]; last[u] = val[fail[u]] ? fail[u] : last[fail[u]]; } } } void print(int j) { if (j) { ans += cnt[j]; cnt[j] = 0; print(last[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]) print(j); else if (last[j]) print(last[j]);//print是功能函数 } } void init() { sz = 1; memset(ch[0],0,sizeof(ch[0])); memset(cnt,false,sizeof(cnt)); } }src; int N; char input[60]; char tag[1000005]; int main() { //freopen("sample.txt","r",stdin); int T; scanf("%d",&T); while (T--) { scanf("%d",&N); gets(input); src.init(); ans = 0; for (int i = 0 ; i < N; i++) { gets(input); src.insert(input,i + 1); } scanf("%s",tag); src.get_fail(); src.Find(tag); printf("%d\n",ans); } return 0; }