zoukankan      html  css  js  c++  java
  • 字符串板子

    kmp

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e6+4;
    char a[maxn],b[maxn];
    int p[maxn];
    int main(){
        scanf("%s",a+1);
        scanf("%s",b+1);
        int n=strlen(a+1),m=strlen(b+1);
        int j=0;
        for(int i=2;i<=m;i++) {
            while(j&&b[j+1]!=b[i]) j=p[j];
            if(b[j+1]==b[i]) j++;
            p[i]=j;
        }
        j=0;
        for(int i=1;i<=n;i++){
            while(j&&b[j+1]!=a[i]) j=p[j];
            if(b[j+1]==a[i]) j++;
            if(j==m){
                printf("%d
    ",i-m+1);
            }
        }
        for(int i=1;i<=m;i++) printf("%d
    ",p[i]);
    }
    kmp

    AC自动机

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e6+4;
    int tot=0;
    struct node{
        int fail,next[26],tag;
    }z[maxn];
    inline void insert(char *s){
        int len=strlen(s);
        int now=0;
        for(int i=0;i<len;i++){
            int v=s[i]-'a';
            if(!z[now].next[v]) z[now].next[v]=++tot;
            now=z[now].next[v];
        }
        z[now].tag++;
    }
    inline void build_AC(){
        queue<int>q;
        for(int i=0;i<26;i++) {
            z[z[0].next[i]].fail=0;
            if(z[0].next[i]) q.push(z[0].next[i]);
        }
        while(!q.empty()){
            int now=q.front();q.pop();
            for(int i=0;i<26;i++){
                if(z[now].next[i]){
                    z[z[now].next[i]].fail=z[z[now].fail].next[i];
                    q.push(z[now].next[i]);
                }else{
                    z[now].next[i]=z[z[now].fail].next[i];
                }
            }
        }
    }
    inline int query(char *s){
        int len=strlen(s);
        int now=0,ans=0;
        for(int i=0;i<len;i++){
            now=z[now].next[s[i]-'a'];
            ans+=z[now].tag;
            z[now].tag=0;
        }
        return ans;
    }

    后缀数组:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e6+4;
    struct node{
        int pos,x[2];//pos开始的位置是哪里,x[0]与x[1]存储用来基数排序的两个值 
        node(){}
        node(int a,int b,int c){
            pos=a;x[1]=b;x[0]=c;
        }
    }x[maxn],sw[maxn];
    char s[maxn];
    int z[maxn],buf[maxn],n,rank[maxn],sa[maxn],height[maxn];
    inline void count_sort(int upper){
        for(int a=0;a<=1;a++){
            memset(buf,0,sizeof(buf));
            for(int b=1;b<=n;b++) buf[x[b].x[a]]++;
            for(int b=1;b<=upper;b++) buf[b]+=buf[b-1];
            for(int b=n;b>=1;b--) sw[buf[x[b].x[a]]--]=x[b];
            for(int b=1;b<=n;b++) x[b]=sw[b];
        }
        int cnt=1;
        rank[x[1].pos]=1;
        for(int a=2;a<=n;a++) {
            if(x[a].x[0]==x[a-1].x[0]&&x[a].x[1]==x[a-1].x[1]) rank[x[a].pos]=cnt;
            else rank[x[a].pos]=++cnt;
        }
    }
    inline void calc_sa(){
        for(int a=1;a<=n;a++) x[a]=node(a,z[a],0);
        count_sort(1000000);//得到所有rank1[i]
        for(int a=1;a<=n;a<<=1){
            for(int b=1;b<=n;b++)
                x[b]=node(b,rank[b],a+b<=n?rank[a+b]:0);
            count_sort(1000000);
        }//rank[i]第i个后缀排名第几 
        for(int a=1;a<=n;a++) sa[rank[a]]=a;//sa[i]排名为i的后缀是第几个后缀 
        for(int a=1;a<=n;a++) {
            int l=height[rank[a-1]];
            if(l>0) l--;
            int p=sa[rank[a]-1];
            while(a+l<=n&&p+l<=n&&s[a+l]==s[p+l]) l++;
            height[rank[a]]=l;
        }
    }
    int main(){
        scanf("%s",s+1);
        n=strlen(s+1);
        for(int i=1;i<=n;i++){
            z[i]=s[i];
        }
        calc_sa();
        for(int i=1;i<=n;i++)printf("%d ",sa[i]);
    }

    Manacher

    #include<iostream>
    #include<cmath>
    #include<cstring>
    #define maxn 51000100
    using namespace std;
    int n,hw[maxn],ans;
    char a[maxn],s[maxn<<1];
    void manacher()
    {
        int maxright=0,mid;
        for(int i=1;i<n;i++)
        {
            if(i<maxright)
                hw[i]=min(hw[(mid<<1)-i],hw[mid]+mid-i);
            else
                hw[i]=1;
            for(;s[i+hw[i]]==s[i-hw[i]];++hw[i]);
            if(hw[i]+i>maxright)
            {
                maxright=hw[i]+i;
                mid=i;
            }
        }
    }
    void change()
    {
        s[0]=s[1]='#';
        for(int i=0;i<n;i++)
        {
            s[i*2+2]=a[i];
            s[i*2+3]='#';
        }
        n=n*2+2;
        s[n]=0;
    }
    int main()
    {
        scanf("%s",a);
        n=strlen(a);
        change();
        manacher();
        ans=1;
        for(int i=0;i<n;i++)
            ans=max(ans,hw[i]);
        printf("%d",ans-1);
        return 0; 
    }
  • 相关阅读:
    两个list,并集、交集、差集
    关于apt-get install
    异步进程池
    获取cpu信息
    print重定向
    使用pandas操作excel
    排列组合,取所有可能性
    list_反转,切片,删除,升序降序
    抠图
    enumerate()函数的用法
  • 原文地址:https://www.cnblogs.com/wifimonster/p/10232827.html
Copyright © 2011-2022 走看看