您的位置:首页 > 其它

算法导论—最长公共子序列

2016-02-24 13:08 357 查看
华电北风吹

日期:2016/2/24

问题描述:

给定两个序列X=(x1,x2,...,xm)和Y=(y1,y2,...,yn),求X和Y的长度最长的公共子序列。

子序列:给定一个序列X=(x1,x2,...,xm),若另一个序列Z=(z1,z2,...,zk)满足存在一个严格递增的下标序列i1,i2,...,ik使得对所有的j=1,2,...,k满足xij=zj,就称Z是X的子序列。

问题解析:

动态规划法图示



参考代码:

#include <string>
#include <iostream>
#include <vector>
using namespace std;

class Solution
{
public:
vector<string> LongestCommanSubArray(string str1,string str2)
{
int m = str1.length();
int n = str2.length();
vector< vector<int>> c(m + 1, vector<int>(n + 1)), b(m + 1, vector<int>(n + 1));
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
if (str1[i] == str2[j])
{
c[i + 1][j + 1] = c[i][j] + 1;
b[i + 1][j + 1] = 0;
}
else
{
if (c[i][j + 1] >= c[i + 1][j])
{
c[i + 1][j + 1] = c[i][j + 1];
b[i + 1][j + 1] = 1;
}
else
{
c[i + 1][j + 1] = c[i + 1][j];
b[i + 1][j + 1] = 2;
}
}
}
}
vector<string> result;
for (int k = n; k > 0; k--)
{
if (c[m][k] == c[m]
)
{
string subresult = "";
int i = m, j = k;
while ((i > 0) && (j > 0))
{
switch (b[i][j])
{
case 0:
subresult.append(1, str1[i - 1]);
i--; j--;
break;
case 1:
i--;
break;
case 2:
j--;
break;
default:
break;
}
}
reverse(subresult.begin(), subresult.end());
result.push_back(subresult);
}
}
return result;
}
};

int main(int argc, _TCHAR* argv[])
{
Solution s;
string s1 = "ABCBDAB", s2 = "BDCABA";
vector<string> result = s.LongestCommanSubArray(s1, s2);
for (auto i : result)
cout << i << endl;

for each (auto i in result)
{
cout << i << endl;
}
getchar();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: