• UVA760 DNA Sequencing


    Description

    多组数据,每组给出两个小写字母组成的字符串,求两个字符串的最长公共子串,如有多个按字典序顺序输出,如没有输出 No common sequence.,每两组数据间输出一个空行,最后一组数据后不应输出空行。

    Solution

    将两个字符串用分隔符连在一起,求出SA

    求出height的最大值,要求这个最大值对应的两个串位于分隔符两侧

    所有相同的答案在height数组中都是连续的,遇到相同就可以跳过

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    int t,len1,len2,sa[615],buc[615],rk[615],x[615],y[615],height[615],m=131,n,ans;
    char S[305],T[305],s[615];
    inline int read(){
        int f=1,w=0;
        char ch=0;
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9')w=(w<<1)+(w<<3)+ch-'0',ch=getchar();
        return f*w;
    }
    void getsa(){
        m=131;
        for(int i=1;i<=m;i++)buc[i]=0;
        for(int i=1;i<=n;i++)++buc[x[i]=s[i]];
        for(int i=2;i<=m;i++)buc[i]+=buc[i-1];
        for(int i=n;i;i--)sa[buc[x[i]]--]=i;
        for(int k=1;k<=n;k<<=1){
            int num=0;
            for(int i=n-k+1;i<=n;i++)y[++num]=i;
            for(int i=1;i<=n;i++)if(sa[i]>k)y[++num]=sa[i]-k;
            for(int i=1;i<=m;i++)buc[i]=0;
            for(int i=1;i<=n;i++)++buc[x[i]];
            for(int i=2;i<=m;i++)buc[i]+=buc[i-1];
            for(int i=n;i;i--)sa[buc[x[y[i]]]--]=y[i],y[i]=0;
            swap(x,y),x[sa[1]]=1,num=1;
            for(int i=2;i<=n;i++)x[sa[i]]=(y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k])?num:++num;
            if(num==n)break;
            m=num;
        }
    }
    void getheight(){
        int k=0;
        for(int i=1;i<=n;i++)rk[sa[i]]=i;
        for(int i=1;i<=n;i++){
            if(rk[i]==1)continue;
            if(k)--k;
            int j=sa[rk[i]-1];
            while(j+k<=n&&i+k<=n&&s[i+k]==s[j+k])++k;
            height[rk[i]]=k;
        }
    }
    int main(){
        while(scanf("%s%s",S+1,T+1)!=EOF){
            ans=0,++t,len1=strlen(S+1),len2=strlen(T+1),s[len1+1]='$';
            if(t>1)putchar(10);
            for(int i=1;i<=len1;i++)s[i]=S[i];
            for(int i=1;i<=len2;i++)s[i+len1+1]=T[i];
            n=len1+len2+1,getsa(),getheight();
            for(int i=2;i<=n;i++)if(sa[i-1]<=len1&&sa[i]>len1+1||sa[i-1]>len1+1&&sa[i]<=len1)ans=max(ans,height[i]);
            if(!ans){puts("No common sequence.");continue;}
            for(int i=2;i<=n;i++)if(height[i]==ans){
                int j=i,k=i;
                while(height[j]==ans)++j;
                for(;k<j;k++)if(sa[k-1]<=len1&&sa[k]>len1+1||sa[k-1]>len1+1&&sa[k]<=len1)break;
                if(k!=j){
                    for(int p=sa[k];p<sa[k]+ans;p++)putchar(s[p]);
                    putchar(10);
                }
                i=j-1;
            }
        }
        return 0;
    }
    DNA Sequencing
  • 相关阅读:
    Vue3源码系列之触发更新的实现
    Vue3源码系列之依赖收集的实现
    Vue3源码系列之reactiveApi实现
    删除链表的倒数第n个节点
    Shared_ptr 参考实现
    linux 目录结构 比较老
    C++11 bind function
    状态机DP
    尾递归
    秒杀系统的构建(2)
  • 原文地址:https://www.cnblogs.com/JDFZ-ZZ/p/14619982.html
Copyright © 2020-2023  润新知