动态规划之两个字符串的最大子序列

1、问题

求两个字符串的最大子序列

1)、子序列和子字符串有区别,子字符串(子串)必须连续,列如

    s1 = "ABCDAB"  s2= "BBCDAAB"

s1和s2最大子序列有"BCDA","BCDB", "CDAB","ABAB","BCAB"...,子序列BCDA是s1和s2的一个LCS

s1和s2最大子字符串是"BCDA"





2、分析

为了找到最长的LCS,我们定义c[i][j]记录序列LCS的长度,公共子序列LCS长度为0,即c[i][j]=0,所以用i和j分别表示序列s1的长度和序列s2的长度,状态转移方程为

    c[i][j] = 0  如果i=0或j=0
    c[i][j] = c[i-1][j-1] + 1  如果s1[i-1] = s2[j-1]
    c[i][j] = max{ c[i-1][j], c[i][j-1] }  如果s1[i-1] != s2[j-1]

我们用一个新的数组C表示新LCS的数组,然后用数组B表示存储位置(值为1的时候表示C数组放的是左上角的数据加一,值为2的时候表示C数组放的左边的数据,值为3的时候,表示C数组放的上面的数据)

比如字符串s1 = "ABCADAB", s2 = "BACDBA"


3、代码实现

#include <iostream>
#include <cstring>

using namespace std;

#define LEN 1024

int c[LEN][LEN], b[LEN][LEN];
char s1[LEN], s2[LEN];

//求最大子序列
void LCS(char *s1, char *s2, int len1, int len2)
{	
	//控制s1序列
	for (int i = 1; i <= len1; ++i)
	{
		//控制s2序列
		for (int j = 1; j <= len2; ++j) 
		{
			if (s1[i - 1] == s2[j - 1])
			{
				c[i][j] = c[i - 1][j - 1] + 1;	
				b[i][j] = 1;
			}
			else 
			{
				if (c[i][j - 1] >= c[i - 1][j])
				{
					c[i][j] = c[i][j - 1];
					b[i][j] = 2;
				}
				else
				{
					c[i][j]	= c[i - 1][j];
					b[i][j] = 3;
				}
			}
		}
	}
}

//打印一个子序列
void print(int i, int j)
{
	//这里是||就行,因为只要挨着任何一条边就行
	if (i == 0 || j == 0) 
		return;
	if(b[i][j] == 1)
	{
		print(i - 1, j -1);
		std::cout << s1[i - 1];
	} 
	else if (b[i][j] == 2)
		print(i, j - 1);
	else
		print(i - 1, j);
}

int main()
{
	std::cout << "请输入2个大写的字符串" << std::endl;
	std::cin >> s1;
	std::cin >> s2;
	int s1_len, s2_len;
	s1_len = strlen(s1);
	s2_len = strlen(s2);
	LCS(s1, s2, s1_len, s2_len);
	std::cout << "s1 和 s2 的最长公共子序列长度是:"<< c[s1_len][s2_len] << std::endl;
	std::cout << "s1 和 s2 的最长公共子序列是:";
	print(s1_len, s2_len);
	return 0;	
}

4、运行结果

/**
请输入2个大写的字符串
ABCADAB
BACDBA
s1 和 s2 的最长公共子序列长度是:4
s1 和 s2 的最长公共子序列是:BADB
**/



5、总结

采用动态规划求解的问题需要具有两个特性:

  • 最优子结构(Optimal Substructure):问题的一个最优解中所包含的子问题的解也是最优的。

  • 重叠子问题(Overlapping Subproblems):用递归算法对问题进行求解时,每次产生的子问题并不总是新问题,有些子问题会被重复计算多次。

问题具有最优子结构性质,我们才能写出最优解的递归方程

阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011068702/article/details/79681295
个人分类: 趣学算法
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭