算法模板の字符串处理

1、AC自动机

 1 void buildTrie(Node *root, char *str){  
 2     Node *p = root;  
 3     for(int i = 0; str[i]; ++i){  
 4         int index = str[i] - '0';  
 5         if(!p->next[index]) p->next[index] = new Node(ecnt++);  
 6         p = p->next[index];  
 7     }  
 8     p->flag = true;  
 9 }  
10      
11 void makeFair(Node *root){  
12     queue<Node*> que; que.push(root);  
13     while(!que.empty()){  
14         Node *tmp = que.front(); que.pop();  
15         for(int i = 0; i < 10; ++i){  
16             if(!tmp->next[i]) continue;  
17             if(tmp == root) tmp->next[i]->fail = root;  
18             else{  
19                 Node *p = tmp->fail;  
20                 while(p){  
21                     if(p->next[i]){  
22                         tmp->next[i]->fail = p->next[i];  
23                         break;  
24                     }  
25                     p = p->fail;  
26                 }  
27                 if(!p) tmp->next[i]->fail = root;  
28             }  
29             if(tmp->next[i]->fail->flag) tmp->next[i]->flag = true;  
30             else que.push(tmp->next[i]);  
31         }  
32     }  
33     root->fail = root;  
34 }
View Code

2、后缀自动机(HDU 1403)

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <cstring>
 4 using namespace std;
 5 
 6 const int MAXN = 100000 + 10;
 7 char buf[MAXN];
 8 struct State {
 9     State *par, *go[26];
10     int val;/*
11     State() :
12             par(0), val(0) {
13         memset(go, 0, sizeof go);
14     }*/
15 }*root, *last;
16 State statePool[MAXN * 2], *cur;
17 
18 void init() {
19     memset(statePool, 0, 2 * strlen(buf) * sizeof(State));
20     cur = statePool;
21     root = last = cur++;
22 }
23 
24 void extend(int w) {
25     State *p = last, *np = cur++;
26     np->val = p->val + 1;
27     while (p && !p->go[w])
28         p->go[w] = np, p = p->par;
29     if (!p) np->par = root;
30     else {
31         State*q = p->go[w];
32         if (p->val + 1 == q->val) np->par = q;
33         else {
34             State *nq = cur++;
35             memcpy(nq->go, q->go, sizeof q->go);
36             nq->val = p->val + 1;
37             nq->par = q->par;
38             q->par = nq;
39             np->par = nq;
40             while (p && p->go[w] == q)
41                 p->go[w] = nq, p = p->par;
42         }
43     }
44     last = np;
45 }
46 
47 int main() {
48     char *pt;
49     while(scanf("%s", buf) != EOF) {
50         init();
51         for (pt = buf; *pt; ++pt)
52             extend(*pt - 'a');
53         scanf("%s", buf);
54         State *t = root;
55         int l = 0, ans = 0;
56         for (pt = buf; *pt; ++pt) {
57             int w = *pt - 'a';
58             if (t->go[w]) {
59                 t = t->go[w];
60                 ++l;
61             } else {
62                 while (t && !t->go[w]) t = t->par;
63                 if (!t) l = 0, t = root;
64                 else {
65                     l = t->val + 1;
66                     t = t->go[w];
67                 }
68             }
69             ans = max(ans, l);
70         }
71         printf("%d
", ans);
72     }
73     return 0;
74 }
View Code

3、后缀数组//字符串末尾要手动添加一个最小字符(比如0)

 1 char s[MAXN];
 2 int sa[MAXN], height[MAXN], rank[MAXN], c[MAXN], tmp[MAXN];
 3 int n;
 4 
 5 void makesa(int m) {
 6     memset(c, 0, m * sizeof(int));
 7     for(int i = 0; i < n; ++i) ++c[rank[i] = s[i]];
 8     for(int i = 1; i < m; ++i) c[i] += c[i - 1];
 9     for(int i = 0; i < n; ++i) sa[--c[rank[i]]] = i;
10     for(int k = 1; k < n; k <<= 1) {
11         for(int i = 0; i < n; ++i) {
12             int j = sa[i] - k;
13             if(j < 0) j += n;
14             tmp[c[rank[j]]++] = j;
15         }
16         int j = c[0] = sa[tmp[0]] = 0;
17         for(int i = 1; i < n; ++i) {
18             if(rank[tmp[i]] != rank[tmp[i - 1]] || rank[tmp[i] + k] != rank[tmp[i - 1] + k])
19                 c[++j] = i;
20             sa[tmp[i]] = j;
21         }
22         memcpy(rank, sa, n * sizeof(int));
23         memcpy(sa, tmp, n * sizeof(int));
24     }
25 }
26 
27 void calheight() {
28     for(int i = 0, k = 0; i < n; height[rank[i++]] = k) {
29         if(k > 0) --k;
30         int j = sa[rank[i] - 1];
31         while(s[i + k] == s[j + k]) ++k;
32     }
33 }
34 
35 int logn[MAXN];
36 int best[20][MAXN];
37 
38 void initRMQ() {
39     logn[0] = -1;
40     for(int i = 1; i <= n; ++i)
41         logn[i] = (i & (i - 1)) == 0 ? logn[i - 1] + 1 : logn[i - 1];
42     for(int i = 1; i <= n; ++i) best[0][i] = height[i];
43     for(int i = 1; i <= logn[n]; ++i) {
44         int ed = n - (1 << i) + 1;
45         for(int j = 1; j <= ed; ++j)
46             best[i][j] = min(best[i - 1][j], best[i - 1][j + (1 << (i - 1))]);
47     }
48 }
49 
50 int lcp(int a, int b) {
51     a = rank[a], b = rank[b];
52     if(a > b) swap(a, b);
53     ++a;
54     int t = logn[b - a + 1];
55     return min(best[t][a], best[t][b - (1 << t) + 1]);
56 }
View Code

4、Manacher(Update:2014年11月13日)

 1 void manacher() {
 2     int mx = 0, id;
 3     for(int i = 1; i < n; ++i) {
 4         if(mx > i) p[i] = min(p[2 * id - i], mx - i);
 5         else p[i] = 1;
 6         while(s[i + p[i]] == s[i - p[i]]) ++p[i];
 7         if(i + p[i] > mx) {
 8             id = i;
 9             mx = i + p[i];
10         }
11     }
12 }
13 
14 void print() {
15     int id = 0;
16     for(int i = 1; i < n; ++i)
17         if(p[i] > p[id]) id = i;
18     int l = (id - p[id] + 1) / 2, r = l + p[id] - 1;
19     for(int i = l; i < r; ++i) putchar(str[i]);// 范围[l, r)
20     puts("");
21 }
22 
23 int main() {//两倍数组大小
24     scanf("%s", str);
25     s[n++] = '$', s[n++] = '#';
26     for(int i = 0; str[i]; ++i) {
27         s[n++] = str[i];
28         s[n++] = '#';
29     }
30     s[n] = 0;
31     manacher();
32     print();
33 }
View Code
原文地址:https://www.cnblogs.com/oyking/p/3678066.html