算法模板の字符串处理

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\n", 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

 

你可能感兴趣的:(字符串处理)