zoukankan      html  css  js  c++  java
  • LCS最长公共子序列HDU1159

    最近一直在学习算法,基本上都是在学习动态规划以及字符串。当然,两者交集最经典之一则是LCS问题。

    首先LCS的问题基本上就是在字符串a,b之间找到最长的公共子序列,比如 YAOLONGBLOG 和 YCLPBPG,其最长公共子序列则是YLBG

    当然当字符串比较大时候,枚举则略显困难。

    首先我们先考虑求一个基本问题,就是LCS的长度。

    很容易可以理解递推式: 

    当a[i]==b[j],c[i][j]=c[i-1][j-1]+1;

    当a[i]!=b[j], c[i][j]=max(c[i-1][j],c[i][j-1]);

    对应HDU1159. 

    Problem Description
    A subsequence of a given sequence is the given sequence with some elements (possible none) left out. Given a sequence X = <x1, x2, ..., xm> another sequence Z = <z1, z2, ..., zk> is a subsequence of X if there exists a strictly increasing sequence <i1, i2, ..., ik> of indices of X such that for all j = 1,2,...,k, xij = zj. For example, Z = <a, b, f, c> is a subsequence of X = <a, b, c, f, b, c> with index sequence <1, 2, 4, 6>. Given two sequences X and Y the problem is to find the length of the maximum-length common subsequence of X and Y. 
    The program input is from a text file. Each data set in the file contains two strings representing the given sequences. The sequences are separated by any number of white spaces. The input data are correct. For each set of data the program prints on the standard output the length of the maximum-length common subsequence from the beginning of a separate line. 
     

    Sample Input
    abcfbc abfcab programming contest abcd mnp
     

    Sample Output
    4 2 0
    这就是裸题啦。利用上面的递推式很容易就写到一个简单的程序。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    using namespace std;
    #define MAX 1000
    int c[MAX][MAX];
    
    int LCS(string a,string b){
    	int n=a.length();
    	int m=b.length();
        memset(c,0,sizeof(c));
    	int i,j;
    	for(i=1;i<=n;i++)
    		for(j=1;j<=m;j++){
    			if(a[i-1]==b[j-1]){
    			    c[i][j]=c[i-1][j-1]+1;
    			}else {
    				c[i][j]=c[i][j-1]>c[i-1][j]?c[i][j-1]:c[i-1][j];
    			
    			}
    		}
    		return c[n][m];
    
    }
    int main(){
    	string a,b;
    	while(cin>>a>>b){
    	   
    	  cout<<LCS(a,b)<<endl;
    	}
    
    
    	
    	return 0;
    
    }

    不过为了体现CPP的模板作用,我还写了另外一个版本,不过没有写成HDU1159的题解,只是一个LCS的实现。


    /*******************************************************************************/
    /* OS           : 3.2.0-58-generic #88-Ubuntu SMP Tue Dec 3 UTC 2013 GNU/Linux
     * Compiler     : g++ (GCC)  4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)
     * Encoding     : UTF8
     * Date         : 2014-03-197
     * All Rights Reserved by yaolong.
    *****************************************************************************/
    /* Description: ***************************************************************
    *****************************************************************************/
    /* Analysis: ******************************************************************
    *****************************************************************************/
    /*****************************************************************************/
    
    
    #include <iostream>
    #include <string>
    #include <cstring>
    using namespace std;
    
    int max(int a,int b){
      return a>b?a:b;
    }
    template<typename Iterator>
    int * lcsLength(Iterator x,Iterator y,int m,int n){
        int *c=new int[(m+1)*(n+1)],i,j;
        for(i=1;i<=m;i++)
            c[i*(n+1)]=0;
        for(j=0;j<=n;j++)
            c[j]=0;
        for(i=1;i<=m;i++)
           for(j=1;j<=n;j++)
              if(*(x+i-1)==*(y+j-1))
                 c[i*(n+1)+j]=c[(i-1)*(n+1)+j-1]+1;
              else c[i*(n+1)+j]=max(c[(i-1)*(n+1)+j],c[(i)*(n+1)+j-1]);
        return c;
    
    }
    template<typename Iterator>
    void printLCS(int *c,int n,Iterator x,Iterator y,int i,int j){
        if(i==0||j==0) return;
        if( *(x+i-1)==*(y+j-1) ){
            printLCS(c,n,x,y,i-1,j-1);
            cout<<*(x+i-1);
        }else if(c[(i-1)*(n+1)+j]>=c[i*(n+1)+j-1])
              printLCS(c,n,x,y,i-1,j);
         else printLCS(c,n,x,y,i,j-1);
    
    
    }
    int main(){
    
        char *x="ACCGGTCGAGTGCGCGGAAGCCGGCCGAA",
             *y="GTCGTTCGGAATGCCGTTGCTCTGTAAA";
         int *c;
         int n=strlen(x),m=strlen(y);
    
         c=lcsLength(x,y,n,m);
         printLCS(c,m,x,y,n,m);
         cout<<endl<<c[ n*(m+1)+m]<<endl;
         delete []c;
    
    
    
    
    
         return 0;
    }
    
    


  • 相关阅读:
    胡昊—第9次作业--接口及接口回调
    胡昊—第8次作业--继承
    软件工程第三次作业——关于软件质量保障初探
    胡昊—第7次作业--访问权限、对象使用
    胡昊—第6次作业—static关键字、对象
    20194670自动生成四则运算题第一版报告
    《现代软件工程—构建之法》第一章总结
    第四次博客作业-结对项目
    第9次作业--接口及接口回调
    第八次作业--继承
  • 原文地址:https://www.cnblogs.com/dengyaolong/p/3697214.html
Copyright © 2011-2022 走看看