课程:THU 数据结构与算法 第一章 绪论 第六节 动态规划
代码参考:https://songlee24.github.io/2014/11/29/print-all-LCS/
自己的实现+注释 107行(包括注释和没什么用的换行)
By 2018-05-25
尽可能的把全局变量局部化(习惯)
#include <iostream>
#include <vector>
#include <string>
#include <set>
#include <algorithm>
using namespace std;
vector<vector<int>> table;//LCS路径表
/*最大子序列长度计算
构造LCS路径表*/
int LCS(string a, string b);
/*追踪所有子序列字符串并一起扔到set里
str为每个最大公共子序列*/
voidTraceBack(string a, string b, string str, set<string>& LCSset);
int main(int argc, char* argv[])
{
string x, y, empty_str;
set<string> LCS_SET;
cin>> x >> y;
cout<< "最大公共子序列的长度是" << LCS(x, y) << endl;
TraceBack(x,y, empty_str, LCS_SET);
//输出
set<string>::iterator beg =LCS_SET.begin();
for (; beg != LCS_SET.end(); ++beg)
cout<< *beg << endl;
system("pause");
return 0;
}
int LCS(string a, string b)
{
//表的大小为 a长+1*b长+1
table= vector<vector<int>>(a.size() + 1, vector<int>(b.size() + 1));
//构造路径表
for (int i = 0; i < a.size() + 1; i++)
for (int j = 0; j < b.size() + 1; j++)
{
if (i == 0 || j == 0)//第一行第一列设0
table[i][j] = 0;
else if (a[i - 1] == b[j - 1])//比对成功+1
table[i][j] = table[i - 1][j - 1] + 1;
else//比对失败继承较大的
table[i][j] = max(table[i - 1][j], table[i][j - 1]);
}
//输出表
for (int i = 0; i < a.size() + 1; ++i)
{
for (int j = 0; j < b.size() + 1; ++j)
{
cout<< table[i][j] << " ";
}
cout<< endl;
}
//返回右下角的值(最大长度)
return table[a.size()][b.size()];
}
//字符串逆序
void Revense(string & str)
{
int low = 0, high = str.length() - 1;
char temp;
while (low < high)
{
temp= str[low];
str[low] = str[high];
str[high] = temp;
low++;high--;
}
}
void TraceBack(string a, string b, string str, set<string>& LCSset)
{
int a_length = a.size(), b_length = b.size();
//用长度递减循环查表(从右下到左上)
while(a_length > 0&& b_length > 0)
{
if (a[a_length - 1] == b[b_length - 1])//相同直接插入
{
str.push_back(a[a_length - 1]);
a_length--;
b_length--;
}
else
{
//若不相同
//如果上面的数值大就往上面走
if (table[a_length - 1][b_length] > table[a_length][b_length - 1])
a_length--;
//如果左边的数值大就往左边走
else if (table[a_length - 1][b_length] < table[a_length][b_length - 1])
b_length--;
//相同的情况下就两边都走
else
{
TraceBack(a.substr(0, a_length- 1), b.substr(0,b_length), str, LCSset);//向上
TraceBack(a.substr(0,a_length), b.substr(0,b_length-1), str, LCSset);//向左
return;
}
}
}
Revense(str);//逆序str(插入的是逆序,返回来
LCSset.insert(str);//每个子序列都放入set中
}