算法之求解最长公共子序列问题

//求解最长公共子序列问题的算法
#include <iostream>
#include <string.h>
#include <vector>
#include <string>
using namespace std;
#define max(x,y) ((x)>(y)?(x):(y))
#define MAX 51							//序列中最多的字符个数
//问题表示
int m,n;
string a,b;
//求解结果表示
int dp[MAX][MAX];						//动态规划数组
vector<char> subs;						//存放LCS
void LCSlength()						//求dp
{
	int i,j;
	for (i=0;i<=m;i++)					//将dp[i][0]置为0,边界条件
		dp[i][0]=0;
	for (j=0;j<=n;j++)					//将dp[0][j]置为0,边界条件
		dp[0][j]=0;
	for (i=1;i<=m;i++)
		for (j=1;j<=n;j++)				//两重for循环处理a、b的所有字符
		{	if (a[i-1]==b[j-1])			//情况(1)
				dp[i][j]=dp[i-1][j-1]+1;
			else						//情况(2)
				dp[i][j]=max(dp[i][j-1],dp[i-1][j]);

		}
}
void Buildsubs()					//由dp构造从subs
{
	int k=dp[m][n];					//k为a和b的最长公共子序列长度
	int i=m;
	int j=n;
	while (k>0)						//在subs中放入最长公共子序列(反向)
		if (dp[i][j]==dp[i-1][j])
			i--;
		else if (dp[i][j]==dp[i][j-1])
			j--;
		else
		{
			subs.push_back(a[i-1]);	//subs中添加a[i-1]
			i--; j--; k--;
		}
}
int main()
{
	a="abcbdb";
	b="acbbabdbb";
	m=a.length();			//m为a的长度
	n=b.length();			//n为b的长度
	LCSlength();			//求出dp
	Buildsubs();			//求出LCS
	cout << "求解结果" << endl;
	cout << "    a: " << a << endl;
	cout << "    b: " << b << endl;
	cout << "    最长公共子序列: ";
	vector<char>::reverse_iterator rit;
	for (rit=subs.rbegin();rit!=subs.rend();++rit)
		cout << *rit;
	cout << endl;
	cout << "    长度: " << dp[m][n] << endl;
  return 0; 
}

其中的LCSlength()方法,即求最长公共子序列长度图解:
在这里插入图片描述
下面是其中buildsubs(),即求最长公共子序列方法讲解
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值