zoukankan      html  css  js  c++  java
  • hdu 2774 后缀数组

    题目大意:

    求两个字符串的最长公共子串

    基本思路:

    首先自然而然的想到应当把两个串拼接起来,为了便于处理,所以在串的中间加个大量(就是一个比其他值大的值),最后别忘了拼接上下标为n的时候是0,调用da函数的时候传n+1,利用height数组,就是遍历height数组,然后就是找height中比res(用来保存结果)大的,且sa[i]和sa[i-1]分别位于两个串里的;

    代码如下:

    #include<cstdio>
    #include<cstring>
    using namespace std;
    
    typedef  long long ll;
    const int inf = 0x3f3f3f3f;
    const int maxn = 200000+10;
    int wa[maxn],wb[maxn],wv[maxn],ws[maxn],sa[maxn],rank[maxn],height[maxn];
    int cmp(int *r,int a,int b,int l){
        return r[a]==r[b]&&r[a+l]==r[b+l];
    }
    void da(int *r,int n,int m){
        int i,j,p,*x=wa,*y=wb,*t;
        for(i=0;i<m;i++) ws[i]=0;
        for(i=0;i<n;i++) ws[x[i]=r[i]]++;
        for(i=1;i<m;i++) ws[i]+=ws[i-1];
        for(i=n-1;i>=0;i--) sa[--ws[x[i]]]=i;
        for(j=1,p=1;p<n;j*=2,m=p){
            for(p=0,i=n-j;i<n;i++) y[p++]=i;
            for(i=0;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j;
            for(i=0;i<n;i++) wv[i]=x[y[i]];
            for(i=0;i<m;i++) ws[i]=0;
            for(i=0;i<n;i++) ws[wv[i]]++;
            for(i=1;i<m;i++) ws[i]+=ws[i-1];
            for(i=n-1;i>=0;i--) sa[--ws[wv[i]]]=y[i];
            for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++) x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;
        }
    }
    void calHeight(int *r,int n){
        int i,j,k=0;
        for(i=1;i<=n;i++) rank[sa[i]]=i;
        for(i=0;i<n;i++){
            if(k) k-=1;
            j=sa[rank[i]-1];
            while(r[i+k]==r[j+k]) k++;
            height[rank[i]]=k;
        }
    }
    int r[maxn];
    char str[maxn];
    
    int main(){
        scanf("%s",str);
        int len=strlen(str);
        int t=len;
        int cnt=0;
        for(int i=0;i<len;i++){
            r[cnt++]=str[i]-'a'+1;
        }
        r[cnt++]=29;
        scanf("%s",str);
        len=strlen(str);
        for(int i=0;i<len;i++){
            r[cnt++]=str[i]-'a'+1;
        }
        r[cnt]=0;
        da(r,cnt+1,30);
        calHeight(r,cnt);
        int maxx=-inf;
        len=t;
        for(int i=2;i<cnt;i++){
            if(height[i]>maxx){
                if(sa[i]>=0&&sa[i]<len&&sa[i-1]>len) maxx=height[i];
                else if(sa[i-1]>=0&&sa[i-1]<len&&sa[i]>len) maxx=height[i];
            }
        }
        printf("%d
    ",maxx);
        return 0;
    }
    

      

  • 相关阅读:
    Solr4.8.0源码分析(12)之Lucene的索引文件(5)
    JAVA基础(1)之hashCode()
    Solr4.8.0源码分析(11)之Lucene的索引文件(4)
    检查数据不一致脚本
    索引的新理解
    数据库放到容器里
    动态规划
    每天晚上一个动态规划
    postgresql parallel join example
    名不正,则言不顺
  • 原文地址:https://www.cnblogs.com/imzscilovecode/p/7995586.html
Copyright © 2011-2022 走看看