• 算法模板の字符串处理


    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
  • 相关阅读:
    正则中的顺序环视和逆序环视
    LeetCode 第 27 场双周赛
    LeetCode 每日一题 198. 打家劫舍
    LeetCode 每日一题 974. 和可被 K 整除的子数组
    LeetCode 每日一题 287. 寻找重复数
    LeetCode 每日一题 4. 寻找两个正序数组的中位数
    LeetCode 每日一题 146. LRU缓存机制
    LeetCode 每日一题 105. 从前序与中序遍历序列构造二叉树
    [转]多线程的那点儿事
    LeetCode 每日一题 5. 最长回文子串
  • 原文地址:https://www.cnblogs.com/oyking/p/3678066.html
Copyright © 2020-2023  润新知