zoukankan      html  css  js  c++  java
  • 0804------算法笔记----------最长公共子序列

    1.动态规划和子序列

      1.1 动态规划的特征:

        a)最优子结构,求问题的解必须获取子问题的最优解;

        b) 重叠子问题,使用原始的递归存在大量的重复计算。

      1.2 子序列的概念:

        a)子序列中的元素都是原字符串中的元素;

        b)子序列中元素的排列顺序,与他们在原字符串中的顺序相一致;

        c)子序列不同于子串,子序列中额元素在原字符串中未必是连续的。

        e)eg.src = "foobar" ,那么 "fbr" 就是一个子序列。

    2.求最长公共子序列的三个版本

      2.1 最原始的递归求解,没有考虑重复计算问题。

    #include <iostream>
    #include <string>
    using namespace std;
    
    int LCS(const string &str1, const string &str2, int i, int j);
    
    int main(int argc, const char *argv[])
    {
        string str1 = "ABCBDAB";
        string str2 = "BDCABA";
        cout << LCS(str1, str2, str1.size(), str2.size()) << endl;
    
        return 0;
    }
    
    // i j 表示长度,即str1的前i个字节 和 str2的前j个字节
    int LCS(const string &str1, const string &str2, int i, int j){
        if(i == 0 || j == 0)
            return 0;
        if(str1[i-1] == str2[j-1]){
            return LCS(str1, str2, i-1, j-1)+1;
        }
        else{
            int ret1 = LCS(str1, str2, i-1, j);
            int ret2 = LCS(str1, str2, i, j - 1);
            return  ret1 > ret2 ? ret1 : ret2 ;
        }
    }

      2.2 画出上述递归树可以看到,大量的分支是重复的,那么重复的计算是否可以避免?显然可以,这里将所有的计算都存储在数组中,那么计算过的值就不会计算第二次,效率会大大提高。

    #include <iostream>
    #include <string>
    #include <string.h>
    
    using namespace std;
    
    int memo[100][100];//全局数组 存储已经计算过的LCS[i][j]
    
    int LCS(const string &str1, const string &str2, int i, int j);
    
    int main(int argc, const char *argv[])
    {
        string str1 = "ABCBDAB";
        string str2 = "BDCABA";
        memset(memo, -1, sizeof memo);
        cout << LCS(str1, str2, str1.size(), str2.size()) << endl;
    
        return 0;
    }
    
    
    // i j 表示长度,即str1的前i个字节 和 str2的前j个字节
    int LCS(const string &str1, const string &str2, int i, int j){
        if(memo[i][j] != -1)
            return memo[i][j];
        if(i == 0 || j == 0)
            return 0;
        if(str1[i-1] == str2[j-1]){
            memo[i][j] = LCS(str1, str2, i-1, j-1) + 1;
            return memo[i][j];
        }
        else{
            int ret1 = LCS(str1, str2, i-1, j);
            int ret2 = LCS(str1, str2, i, j - 1);
            memo[i][j] = ret1 > ret2 ? ret1 : ret2;
            return memo[i][j];
        }
    }

      2.3 非递归方法。从串长度为 0 开始依次求解,这里可作图研究,执行的过程就是填充一个二维数组的过程。

    #include <iostream>
    #include <string>
    #include <stdlib.h>
    #include <string.h>
    using namespace std;
    /*
     * 最长公共子串
     */
    
    
    int main(int argc, const char *argv[])
    {
        if(argc != 3){
           cout << "Too Few Arguments" << endl;
           exit(EXIT_FAILURE);
        }
        string str1 = argv[1];
        string str2 = argv[2];
        int memo[100][100];
        memset(memo, -1, sizeof memo);
        int i, j;
        for(i = 0; i <= str1.size(); i++)
            for(j = 0; j <= str2.size(); j++){
                if(i == 0 | j == 0)
                    memo[i][j] = 0;
                else{
                    if(str1[i-1] == str2[j-1])
                        memo[i][j] = memo[i-1][j-1] + 1;
                    else
                        memo[i][j] = memo[i-1][j] > memo[i][i-1] ? memo[i-1][j] : memo[i][j-1];
                }
            }
        cout << memo[str1.size()][str2.size()] << endl;
    
        return 0;
    }
    

      

     

  • 相关阅读:
    New Audio Codec (3) : Design of a Scalable Parametric Audio Coder(可分级正弦模型)
    英国旅游庄园酒店
    圣塔芭芭拉加州大学 信号压缩实验室
    mptkcodec工程(二):VS2008+Win7 编译 mptkcodec(下)
    SPIHT 编码原理,代码,应用,专利问题
    Audio Bandwidth Extension 技术主页
    【quote】free HRTF Databases available online
    New Audio Codec (4) : Daryl Ning 的 Warped LPC and Wavelet Audio Coding 方案
    mptkcodec工程(二):VS2008+Win7 编译 mptkcodec(上)
    mptkcodec工程(一):Cygwin+Win7 编译 mptkcodec
  • 原文地址:https://www.cnblogs.com/monicalee/p/3891349.html
Copyright © 2011-2022 走看看