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


  • 相关阅读:
    .NET Core微服务开发服务间调用篇-GRPC
    .NET Core微服务开发网关篇-ocelot
    刷新.NET
    (译)An introduction to Kubernetes
    一文了解Nuget的使用
    .NET Core应用框架AA介绍(二)
    .NET Core 3.0 使用Nswag生成Api文档和客户端代码
    .NET core3.0 使用Jwt保护api
    阅读源码学设计模式-单例模式
    .NET Core 3.0 部署在docker上运行
  • 原文地址:https://www.cnblogs.com/dengyaolong/p/3697214.html
Copyright © 2011-2022 走看看