算法原理见算法导论
核心思想动态规划———-自底向上方法
// 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;
}