如何将字符串保存在最长的常见子序列递归算法中

how to save string in longest common subsequence recursive algorithm

本文关键字:常见 递归算法 字符串 保存 存在      更新时间:2023-10-16

我正在尝试实现最长常见子序列算法的幼稚方法。我正在使用递归方法,将两个字符串传递到功能lcs中。我成功地计算了最长的子序列中的字符数量。

我的问题是打印LCS的字符。我以为我可以通过将匹配的字符存储在名为sub的字符串中并将其作为参数传递来做到这一点。但是,我坚持如何保存字符串。我一直在递归方面挣扎,并希望以正确的方式解决此问题的任何技巧。

#include <iostream>
#include <string>
#include <math.h>
using namespace std;
int lcs(string a, string b,string sub){
    int aLen = a.length();
    int bLen = b.length();
    if (aLen==0 || bLen==0){
        return 0;
    }
    if(a.at(aLen-1)==b.at(bLen-1)){
        return 1+lcs(a.substr(0,aLen-1),b.substr(0,bLen-1),a.at(aLen-1)+sub); // add letter to subsequence
    }
    else {
        return max(lcs(a.substr(0,aLen-1),b.substr(0,bLen),sub),lcs(a.substr(0,aLen),b.substr(0,bLen-1),sub));
    }
}
int main(int argc, const char * argv[])
{
    char sub[]="";
    int charsInLCS = lcs("sdmc","msdc",sub); //i want to output "sdc"
    cout << charsInLCS << endl;
    return 0;
}

请小心,您的基本情况是错误的,因为您永远不会对B [0]检查A [0]。此外,通过弦副本非常昂贵,只能通过索引并与之合作的速度更快。我们需要跟踪a[idxa] == b[idxb]时匹配的字符。这是使用向量的解决方案:

#include <iostream>
#include <string>
#include <queue>
#include <math.h>
#include <algorithm>    // std::reverse
using namespace std;
string s1, s2;
int lcs(int idx1, int idx2, vector<char> &v){
    if (idx1 == -1 || idx2 == -1){
        return 0;
    }
    if (s1[idx1] == s2[idx2]) {
        v.push_back(s1[idx1]); // record that we used this char
        return 1 + lcs(idx1 - 1, idx2 - 1, v);
    } else {
        vector<char> v1, v2;
        int p1 = lcs(idx1 - 1, idx2, v1); 
        int p2 = lcs(idx1, idx2 - 1, v2);
        if (p1 > p2) { // we used the chars we already had in v + the ones in v1
            v.insert(v.end(), v1.begin(), v1.end());
            return p1;
        } else { // we used the chars we already had in v + the ones in v2
            v.insert(v.end(), v2.begin(), v2.end());
            return p2;
        }
    }
}
int main(int argc, const char * argv[])
{
    s1 = "sdmc";
    s2 = "msdc";
    vector<char> v; // chars we used
    int sol = lcs(s1.length() - 1, s2.length() - 1, v); //i want to output "sdc"
    cout << sol << " ";
    reverse(v.begin(), v.end());
    for (auto num : v) {
        cout << num;
    }
    return 0;
}