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;
    }
    
    


  • 相关阅读:
    c++下使用邮槽实现进程间通信
    c++下基于windows socket的多线程服务器(基于TCP协议)
    C++实现线程同步的几种方式
    c++多线程编程:实现标准库accumulate函数的并行计算版本
    c++多线程在异常环境下的等待
    c++下基于windows socket的服务器客户端程序(基于UDP协议)
    c++下基于windows socket的单线程服务器客户端程序(基于TCP协议)
    C++解决error C4996报错
    Python读取UTF-8编码文件并使用命令行执行时输出结果的问题
    P4655 [CEOI2017]Building Bridges 题解
  • 原文地址:https://www.cnblogs.com/dengyaolong/p/3697214.html
Copyright © 2011-2022 走看看