【模板】字符串系列算法

一、KMP

CODE:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cmath>
 4 #include<algorithm>
 5 #define rep(i,a,n) for(int i = a;i <= n;i++)
 6 #define per(i,n,a) for(int i = n;i >= a;i--)
 7 #define inf 2147483647
 8 #define ms(a,b) memset(a,b,sizeof(a))
 9 using namespace std;
10 typedef long long ll;
11 ll read() {
12     ll as = 0,fu = 1;
13     char c = getchar();
14     while(c < '0' || c > '9') {
15         if(c == '-') fu = -1;
16         c = getchar();
17     } 
18     while(c >= '0' && c <= '9') {
19         as = as * 10 + c - '0';
20         c = getchar();
21     }
22     return as * fu;
23 }
24 const int N = 1000005;
25 //head
26 
27 int nxt[N];
28 char s[N],t[N];
29 
30 void init(int m) {
31     int tmp = 0;
32     rep(i,2,m) {
33         while(tmp && t[tmp+1] != t[i]) 
34             tmp = nxt[tmp];
35         if(t[tmp+1] == t[i]) nxt[i] = ++tmp;
36     }
37 }
38 
39 void KMP(int n,int m) {
40     int tmp = 0;
41     rep(i,1,n) {
42         while(tmp && t[tmp+1] != s[i]) tmp = nxt[tmp];
43         if(t[tmp+1] == s[i]) {
44             tmp++;
45             if(tmp == m) printf("%d\n",i-tmp+1);
46         }
47     }
48 }
49 
50 int main() {
51     scanf("%s",s+1);
52     scanf("%s",t+1);
53     int n = strlen(s+1);
54     int m = strlen(t+1);
55     init(m);
56     KMP(n,m);
57     rep(i,1,m) printf("%d ",nxt[i]);
58     puts("");
59     return 0;
60 }

 

 

二、manacher

CODE:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 #define rep(i,a,n) for(int i = a;i <= n;i++)
 6 #define per(i,n,a) for(int i = n;i >= a;i--)
 7 #define ms(a,b) memset(a,b,sizeof a)
 8 #define inf 2147483647
 9 using namespace std;
10 typedef long long ll;
11 ll read() {
12     ll as = 0,fu = 1;
13     char c = getchar();
14     while(c < '0' || c > '9') {
15     if(c == '-') fu = -1;
16     c = getchar();
17     }
18     while(c >= '0' && c <= '9') {
19     as = as * 10 + c - '0';
20     c = getchar();
21     }
22     return as * fu;
23 }
24 const int N = 20000005;
25 //head
26 int n,ans,top;
27 char m[N],s[N<<1];
28 int len[N];//'#' --> x/2.0 --> len
29 void init() {
30     top = 0;
31     s[top] = '#';
32     s[++top] = '#';
33     n = strlen(m);
34     rep(i,0,n-1) {
35     s[++top] = m[i];
36     s[++top] = '#';
37     }
38     s[++top] = 0;
39 }
40 
41 void manacher() {
42     int mr = 0,mid;
43     rep(i,1,top-1) {
44            if(i < mr) len[i] = min(len[(mid<<1)-i],len[mid] + mid - i);
45     else len[i] = 1;
46     while(s[i + len[i]] == s[i - len[i]]) len[i]++;
47     if(len[i] + i > mr) {
48         mr = len[i] + i;
49         mid = i;
50     }
51     }
52 }
53 
54 
55 
56 int main() {
57     scanf("%s",m);
58     init();
59 //    puts(s);
60     manacher();
61     rep(i,0,top-1) ans = max(ans,len[i]);
62     printf("%d\n",ans-1);
63     return 0;
64 }

三、AC_automaton

Code:

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<queue> 
 6 #define rep(i,a,n) for(int i = a;i <= n;i++)
 7 #define per(i,n,a) for(int i = n;i >= a;i--)
 8 #define enter putchar('\n')
 9 
10 using namespace std;
11 const int N = 500005;
12 const int M = 1000005;
13 typedef long long ll;
14 
15 int read()
16 {
17     int ans = 0,op = 1;
18     char ch = getchar();
19     while(ch < '0' || ch > '9')
20     {
21     if(ch == '-') op = -1;
22     ch = getchar();
23     }
24     while(ch >= '0' && ch <= '9')
25     {
26     ans *= 10;
27     ans += ch - '0';
28     ch = getchar();
29     }
30     return ans * op;
31 }
32 
33 queue<int> q;
34 int t,sum[200],maxn;
35 char str[M],s[200][200];
36 struct ACG
37 {
38     int c[N][26],p[N],fail[N],cnt,d[N];
39     void clear()
40     {
41     memset(c,0,sizeof(c));
42     memset(fail,0,sizeof(fail));
43     memset(d,0,sizeof(d));
44     memset(p,0,sizeof(p));
45     cnt = 0;
46     }
47     void insert(char *s,int f)
48     {
49     int len = strlen(s),now = 0;
50     rep(i,0,len-1)
51     {
52         int v = s[i] - 'a';
53         if(!c[now][v]) c[now][v] = ++cnt;
54         now = c[now][v];
55     }
56     p[now]++,d[now] = f;
57     }
58     void getfail()
59     {
60     rep(i,0,25) if(c[0][i]) fail[c[0][i]] = 0,q.push(c[0][i]);
61     while(!q.empty())
62     {
63         int k = q.front();q.pop();
64         rep(i,0,25)
65         {
66         if(c[k][i]) fail[c[k][i]] = c[fail[k]][i],q.push(c[k][i]);
67         else c[k][i] = c[fail[k]][i];
68         }
69     }
70     }
71     void match(char *s)
72     {
73     int len = strlen(s),now = 0;
74     rep(i,0,len-1)
75     {
76         now = c[now][s[i] - 'a'];
77         for(int g = now;g && p[g] != -1;g = fail[g])
78         {
79         if(p[g]) sum[d[g]]++;
80         //else p[g] = -1;
81         }
82     }
83     }
84 }AC;
85 int main()
86 {
87     while(1)
88     {
89     t = read(); if(!t) break;
90     AC.clear(),memset(sum,0,sizeof(sum)),maxn = 0;
91     rep(i,1,t) scanf("%s",s[i]),AC.insert(s[i],i);
92     AC.getfail();
93     scanf("%s",str),AC.match(str);
94     rep(i,1,t) maxn = max(maxn,sum[i]);
95     printf("%d\n",maxn);
96     rep(i,1,t) if(sum[i] == maxn) printf("%s\n",s[i]);
97     }
98     return 0;
99 }
posted @ 2018-10-03 22:37  白怀潇  阅读(159)  评论(0)    收藏  举报