• POJ-2774 后缀数组基础题


    POJ 2774

    题意:求两个字符串的最长公共子串。

    总结:搞了半天还是不太理解,看着大神博客强行敲的。。而且还看到有hash+二分做的。

    // POJ-2774
    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<map>
    #include<bitset>
    #include<vector>
    #include<set>
    using namespace std;
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define F(i,a,b)  for (int i=a;i<b;i++)
    #define FF(i,a,b) for (int i=a;i<=b;i++)
    #define mes(a,b)  memset(a,b,sizeof(a))
    #define INF 0x3f3f3f3f
    typedef long long ll;
    const int N = 3e5+10;
    
    char str[N], str1[N];
    
    //这些应该可以做模板了。。
    int wa[N], wb[N], wsf[N], wv[N], sa[N];
    int rankn[N], height[N], s[N];
    int cmp(int *r, int a, int b, int k)
    {
        return r[a]==r[b] && r[a+k]==r[b+k];
    }
    void Getsa(int *r, int *sa, int n, int m)
    {
        int i, j, p, *x=wa, *y=wb, *t;
        F(i,0,m) wsf[i]=0;
        F(i,0,n) wsf[x[i]=r[i]]++;
        F(i,1,m) wsf[i]+= wsf[i-1];
        for(i=n-1; i>=0; i--) sa[--wsf[x[i]]]=i;
        p=1, j=1;
        for( ; p<n; j*=2, m=p) {
            for(p=0, i=n-j; i<n; i++) y[p++]=i;
            F(i,0,n) if(sa[i]>=j) y[p++]=sa[i]-j;
            F(i,0,n) wv[i]=x[y[i]];
            F(i,0,m) wsf[i]=0;
            F(i,0,n) wsf[wv[i]]++;
            F(i,1,m) wsf[i]+= wsf[i-1];
            for(i=n-1; i>=0; i--) sa[--wsf[wv[i]]]=y[i];
            t=x, x=y, y=t;
            x[sa[0]]=0;
            for(p=1, i=1; i<n; i++)
                x[sa[i]]= cmp(y, sa[i-1], sa[i], j) ? p-1 : p++;
        }
    }
    void Getheight(int *r, int n)
    {
        int i, j, k=0;
        FF(i,1,n) rankn[sa[i]]=i;
        F(i,0,n) {
            if(k) k--;
            else k=0;
            j=sa[rankn[i]-1];
            while(r[i+k]==r[j+k]) k++;
            height[rankn[i]]=k;
        }
    }
    
    
    int main()
    {
        while(~scanf("%s%s", str, str1)) {
            int n=0, len=strlen(str);
            F(i,0,len) s[n++]= str[i]-'a'+1;
            s[n++]=28;
            len=strlen(str1);
            F(i,0,len) s[n++]= str1[i]-'a'+1;
            s[n]=0;    //把两个字符串并到一起,中间和结尾加上标识符
    
            Getsa(s, sa, n+1, 30);
            Getheight(s, n);
            int maxn=0, pos=0;
            len=strlen(str);
            F(i,2,n) if(height[i]>maxn) {   //找出一个height值最大并且i与i-1的sa值分别在两串字符中
                if(0<=sa[i-1] && sa[i-1]<len && len<sa[i])
                    maxn=height[i];
                if(0<=sa[i] && sa[i]<len && len<sa[i-1])
                    maxn=height[i];
            }
            printf("%d
    ", maxn);
        }
    
        return 0;
    }
  • 相关阅读:
    redis面试题总结
    TP5隐藏index.php
    php四种文件加载语句
    【Redis缓存机制】1.Redis介绍和使用场景
    Linux cpufreq 机制了解 arm
    数码设备发展的核心:分离,互联网营销 狼人:
    豆瓣:“慢公司”,互联网营销 狼人:
    互联网周刊:互联网进化论,互联网营销 狼人:
    怀念中国雅虎:技术文化和惨淡命运,互联网营销 狼人:
    菜鸟玩GAE(Google App Engine)完全指南,互联网营销 狼人:
  • 原文地址:https://www.cnblogs.com/sbfhy/p/6353298.html
Copyright © 2020-2023  润新知