最长公共子序列的经典c++解法

算法原理见算法导论
核心思想动态规划———-自底向上方法

// resize是改变容器的大小,且在创建对象,因此,调用这个函数之后
//就可以引用容器内的对象了,因此当加入新的元素时,用operator[]操作符
#include"stdafx.h"
#include "iostream"  
#include "string"  
#include "vector"  
using namespace std;
vector<char> common;
int lcs(string A, string B) {
    vector<vector<int> > len;
    len.resize(A.size() + 1);//这样的话可以直接使用[],切记
    for (int i = 0; i <= A.size(); i++) {
        len[i].resize(B.size() + 1, 0);
    }
    //3种情况
    for (int i = 1; i <= A.size(); ++i)
    {
        for (int j = 1; j <= B.size(); ++j)
        {
            if (A[i - 1] == B[j - 1])//值相等
            {
                len[i][j] = len[i - 1][j - 1] + 1;
            }
            else if (len[i - 1][j] >= len[i][j - 1])
            {
                len[i][j] = len[i - 1][j];
            }
            else {
                len[i][j] = len[i][j - 1];
            }
        }
    }
    int apos = A.size();
    int bpos = B.size();
    int commonlen = len[apos][bpos];//公共子序列的长度
    int k = commonlen;
    common.resize(commonlen);//这样的话能够使用【】进行赋值
    //下面是输出公共子序列
    //仍然是三种情况
    while (apos && bpos) {
        if (len[apos][bpos] == len[apos - 1][bpos] + 1) {
            common[--k] = A[--apos];//对其赋值比较方便,不需要使用push_back(),然后还行要反转序列
            --bpos;
        }
        else if (len[apos - 1][bpos] >= len[apos][bpos - 1])
        {
            --apos;
        }
        else {
            --bpos;
        }
    }
    for (int i = 0; i < commonlen; i++) {
        cout << common[i];
    }
    cout << endl;
    return commonlen;//返回的值是个数
}
//测试
int main(int argc, char const *argv[])
{
    string A = "abcbdab";
    string B = "bdcaba";
    cout << lcs(A, B);
    return 0;
}

你可能感兴趣的:(Leetcode)