簡體   English   中英

如何在最長的公共子序列遞歸算法中保存字符串

[英]how to save string in longest common subsequence recursive algorithm

我正在嘗試實現最長的通用子序列算法的幼稚方法。 我正在使用遞歸方法,將兩個字符串傳遞給函數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;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM