最长公共子序列长度函数没有返回正确的长度?

Posted

技术标签:

【中文标题】最长公共子序列长度函数没有返回正确的长度?【英文标题】:Longest Common Subsequence Length function not returning the correct length? 【发布时间】:2012-11-23 03:09:47 【问题描述】:

我试图实现动态规划方法来查找两个序列之间的最长公共子序列。我的算法在被比较的两个字符串长度相同时起作用,但是当第二个字符串比第一个字符串长时,我的 LCSLength() 函数不会返回正确的值。

这是带有返回错误值的测试用例的代码。

#include <iostream>
#include <string>
#include <fstream>

using namespace std;

int LCSLength(string X,string Y);

int main()

    string first ("HELLO");
    string second ("HLOCKKE");
    int LCS;

    //ifstream inData;
    //inData.open("test.dat");

    //inData >> first >> second;
    //inData.close();

    LCS = LCSLength(first,second);
    cout << "The LCS is: " << LCS << endl;
    cout << first << endl;
    cout << second << endl;
    return 0;


int LCSLength(string X,string Y)

    int m = X.size();
    int n = Y.size();
    int C[m][n];
    for(int i=0; i<=m; i++)
    
        for(int j=0; j<=n; j++)
            C[i][j] = 0;
    
    for(int i=1; i<=m; i++)
    
        for(int j=1; j<=n; j++)
        
            if(X[i-1]==Y[j-1])
                C[i][j]=C[i-1][j-1]+1;
            else 
                C[i][j]=max(C[i][j-1],C[i-1][j]);
       
    

    return C[m][n];

这应该打印“The LCS is: 3”,因为我的两个字符串之间的 LCS 是 3,但是,我的程序没有。我找不到我的错误。谢谢您的帮助。

【问题讨论】:

我发现一个错误 - 进行了编辑。仍然没有返回正确的值。 它返回什么?你为什么期待3?我能看到的最长的共同部分是LO,即2 我期待3,因为最长的公共子序列是HLO。对于这个特定的例子,我的程序返回4 en.wikipedia.org/wiki/Longest_common_subsequence_problem 我不明白你的代码应该如何工作。您违反了 C[m][n] 数组的边界,这是一种未定义的行为 【参考方案1】:

使用一些谷歌搜索修复了我的错误。索引是我的问题。这是正确的代码:

#include <iostream>
#include <string>
#include <fstream>


using namespace std;

int LCSLength(string X,string Y);

int main()

    string first ("HELLO");
    string second ("HLOCKKE");
    int LCS;

    //ifstream inData;
    //inData.open("test.dat");

    //inData >> first >> second;
    //inData.close();

    LCS = LCSLength(first,second);
    cout << "The LCS is: " << LCS << endl;
    cout << first << endl;
    cout << second << endl;
    return 0;


int LCSLength(string X,string Y)

    int m = X.size();
    int n = Y.size();
    int L[m+1][n+1];
    for(int i=0; i<=m; i++)
    
        for(int j=0; j<=n; j++)
        
            if(i==0 || j==0)
                L[i][j] = 0;
            else if(X[i-1]==Y[j-1])
                L[i][j] = L[i-1][j-1]+1;
            else
                L[i][j] = max(L[i-1][j],L[i][j-1]);
        
    
    return L[m][n];

【讨论】:

实际上,情况正好相反:for 循环应该在 i&lt;mj&lt;n(不是“小于或等于”)时迭代。在大多数类 C 语言中,数组是从 0 开始的,这意味着 n 项的数组具有从 0n-1 的索引,包括端点。

以上是关于最长公共子序列长度函数没有返回正确的长度?的主要内容,如果未能解决你的问题,请参考以下文章

最长递归子序列最长公共字串最长公共子序列编辑距离

网易2017秋招笔试题3:最长公共子括号序列长度

MATLAB 最长公共子序列

codevs 1862 最长公共子序列(求最长公共子序列长度并统计最长公共子序列的个数)

最长公共子序列

最长公共子序列