《github一天一道算法题》:动态规划法解决最长公共子序列(LCS)问题的最简单方法

<pre name="code" class="cpp">/*
 * [email protected]
 * 问题:longest common subsequece problem
 * 思路:从底往上,利用动态规划,划分子问题,利用LCS子问题的长度变化,求得LCS
 * 时间复杂度O(m*n)
 * 空间复杂度O(m*n)
*/
#include <iostream>
//#include <string>
using namespace std;

class lcs
{
  public:
    lcs(char *a,int m, char *b, int n):_a(a),a_length(m),_b(b),b_length(n)//传递两个字符串,并传递其长度
    {
        for(int i=0;i<100;i++)
        {
            for(int j=0;j<100;j++)
                count[i][j]=0;
        }
        if(max(sizeof(a),sizeof(b))>100)
            cout<<"error! count[100][100] too small!"<<endl;

    }
    ~lcs()
    {
        if(_a!=NULL)
        {
            delete _a;
            _a=NULL;
        }
        if(_b!=NULL)
        {
            delete _b;
            _b=NULL;
        }
    }
void get_lcs();
private:
    char *_a;                //字符串一
    int a_length;             //长度
    char *_b;                //字符串二
    int b_length;            //长度
    int count[100][100];     //LCS长度二维状态数组
};

/*              0                                  i=0 or j=0
 *
 *count[i][j]=  count[i-1][j-1]+1                  X[i-1]==Y[j-1] and i ,j>0
 *
 *              max(count[i-1][j],count[i][j-1])   X[i-1]!=Y[j-1] and i ,j>0
*/
void lcs::get_lcs()
{
    int m=a_length;
    int n=b_length;
    for(int i=1;i<=m;i++)
    {
        for(int j=1;j<=n;j++)
        {
           if(*(_a+i-1)==*(_b+j-1))
           {
               count[i][j]=count[i-1][j-1]+1;
           }
           else if(count[i-1][j]>=count[i][j-1])
           {
               count[i][j]=count[i-1][j];
           }
           else
               count[i][j]=count[i][j-1];
        }//for
    }
    /*打印LCS长度二维数组*/
    for(int i=1;i<=m;i++)
    {
        for(int j=1;j<=n;j++)
            cout<<count[i][j]<<" ";
        cout<<endl;
    }
    /*LCS 长度*/
    cout<<"LCS length:"<<count[m][n]<<endl;
    /*输出LCS,这里有一个技巧,就是分别增加一个字符串的长度和另外一整个个字符串比较,LCS长度增加1,说明该位置是LCS的一个字符*/
    cout<<"LCS is:"<<endl;
    for(int p=1;p<=n;p++)
    {
        if(count[m][p]-count[m][p-1]==1)
            cout<<*(_b+p-1)<<" ";
    }
    cout<<endl;
}

int main()
{
    char a[]="ABCBDAB";
    cout<<a<<endl;
    char b[]="BECBD";
    cout<<b<<endl;
    lcs mylcs(a,sizeof(a)-1,b,sizeof(b)-1);
    mylcs.get_lcs();

}

结果:

时间: 2024-10-29 19:08:00

《github一天一道算法题》:动态规划法解决最长公共子序列(LCS)问题的最简单方法的相关文章

实习生面试--算法题之字符串最长公共子序列长度

题目:求两字符串的最长公共子序列的长度. 题外话:最长公共子串,子序列问题是被充分讨论的问题,网上一搜一大把,请bing之. 本题只要求求最长公共子序列的长度,而不需要记录最长的公共子序列,给予了我们便利,请参考代码: 1 int max(int a, int b) 2 { 3 return a > b ? a : b; 4 } 5 6 int lcs(char* str1, char* str2) 7 { 8 if (str1 == nullptr || str2 == nullptr) 9

每周一道算法题011:最长公共子串

问题: 求以下几组单词的最长公共子串的长度1.fish和fosh2.fish和hish3.fish和vista 思路: 可以用表格法,横纵坐标分别是两个单词,如果字符相同,就用左上角的数字加1,最后取表格中的最大值. 解答: php: <?php // 找出两个单词的最长公共子串 function findLongestSubString($word1, $word2) { $len1 = strlen($word1); $len2 = strlen($word2); $cell = array

动态规划算法解最长公共子序列LCS问题

第一部分.什么是动态规划算法 ok,咱们先来了解下什么是动态规划算法. 动态规划一般也只能应用于有最优子结构的问题.最优子结构的意思是局部最优解能决定全局最优解(对有些问题这个要求并不能完全满足,故有时需要引入一定的近似).简单地说,问题能够分解成子问题来解决. 动态规划算法分以下4个步骤: 描述最优解的结构 递归定义最优解的值 按自底向上的方式计算最优解的值   //此3步构成动态规划解的基础. 由计算出的结果构造一个最优解.   //此步如果只要求计算最优解的值时,可省略. 好,接下来,咱们

动态规划解决最长公共子序列问题(转)

原文链接 动态规划法 经常会遇到复杂问题不能简单地分解成几个子问题,而会分解出一系列的子问题.简单地采用把大问题分解成子问题,并综合子问题的解导出大问题的解的方法,问题求解耗时会按问题规模呈幂级数增加. 解决思想: 为了节约重复求相同子问题的时间,引入一个数组,不管它们是否对最终解有用,把所有子问题的解存于该数组中,这就是动态规划法所采用的基本方法. [问题] 求两字符序列的最长公共字符子序列 问题描述:字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后

算法导论之动态规划(最长公共子序列和最优二叉查找树)

动态规划师通过组合子问题的解而解决整个问题,将问题划分成子问题,递归地求解各子问题,然后合并子问题的解而得到原问题的解.和分治算法思想一致,不同的是分治算法适合独立的子问题,而对于非独立的子问题,即各子问题中包含公共的子子问题,若采用分治法会重复求解,动态规划将子问题结果保存在一张表中,避免重复子问题重复求解. 动态规划在多值中选择一个最优解,其算法设计一般分为4个步骤:描述最优解的结构:递归定义最优解的值:按自底向上的方式计算最优解的值:由计算出的结果构造一个最优解. 1)装配线调度 求解最快

算法导论--动态规划(最长公共子序列)

最长公共子序列问题(LCS) 给定两个序列X=?x1,x2,x3...xm?和Y=?y1,y2,y3...xn?,求X和Y的最长公共子序列. 例如:X=?A,B,C,B,D,A,B?,和Y=?B,D,C,A,B,A?,的最长公共子序列为?B,C,B,A?,长度为4: 对于此问题,可以采用暴力求解的方式来比对,即穷举出X的所有子序列,用每个子序列与y做一 一比较.假如X序列共有m个元素,对每个元素可以决定选或不选,则X的子序列个数共有2m个,可见与长度m呈指数阶,这种方法效率会很低. 动态规划 前

编程算法 - 最长公共子序列(LCS) 代码(C)

最长公共子序列(LCS) 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 给定两个字符串s,t, 求出这两个字符串最长的公共子序列的长度. 字符串的子序列并一定要连续, 能够包含间隔. 即最长公共子序列问题(LCS, Longest Common Subsequence) 使用动态规划, 假设字符相等, 两个字符串就依次递增一位, 一直到字符串的结尾. 代码: /* * main.cpp * * Created on: 2014.7.17

算法重拾之路——最长公共子序列(LCS)

***************************************转载请注明出处:http://blog.csdn.net/lttree******************************************** 第二章:动态规划 最长公共子序列 算法描述: 一个给定序列的子序列是该序列中删去若干元素后得到的序列.确切的说,若给定序列 X={ x1,x2,...,xm },则另一序列 Z = { z1,z2, ... ,zk },是X的子序列是指存在一个严格递增下标序列

《github一天一道算法题》:搜索二叉树接口实现大合集

读书.思考.写代码! 说明: (1)这里实现了搜索二叉树的全部常用操作 (2)限于时间和精力,实现的较为粗糙,内存泄露.成员变量访问控制.返回类型.异常安全等没有照顾的到 (3)一切实现的手段都是贴近底层操作,关注原理.以后可能对推倒重来,实现一个完备的接口系统. /********************************************* * [email protected] * 题目:二叉树接口实现大合集 * 具体:二叉树的创建.插入.最大值.最小值.前中后序递归遍历与非递