例题分享——最长公共子序列问题(LCS)

题目

注意:两个字符串的最长公共子串(DP)与最长公共子序列(LCS)的区别:
最长公共子串要求在原字符串中是连续的,而子序列只需要保持相对顺序一致,并不要求连续。

分析

根据standFord《算法导论》课程的方法一共有3种办法

  1. 暴力穷举法,这个不用说了都知道。
  2. 动态递归,也就是利用递归思路,自上而下。从m ->0。
  3. 备忘表法,自下而上(自底向上)。从0 ->m。备忘表法会丢到一些内容

2/3无论哪一个都是利用同一个核心:状态转移方程。(从别人的文章中看到的,我也忘记是哪里带来的了。)
f ( m , n ) = { 0 , m = 0 ∣ ∣ n = 0 f ( m − 1 , n − 1 ) + 1 , a [ m ] = b [ n ] m a x ( f ( m − 1 , n ) , f ( m − 1 , n ) ) , a [ m ] ≠ b [ n ] f(m,n) = \begin{cases} 0,& m=0||n=0\\ f(m-1,n-1) +1, &a[m]=b[n]\\ max(f(m-1,n),f(m-1,n)),&a[m] \neq b[n] \end{cases} f(m,n)=0,f(m1,n1)+1,max(f(m1,n),f(m1,n)),m=0n=0a[m]=b[n]a[m]̸=b[n]

代码

#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;

#define  MAX_X 1000
#define  MAX_Y 1000


string Result[MAX_X][MAX_Y];//由于C++中字符串自动初始化为"",不能判断是否为空,所以需要另外一个表格来判断是否已经有值了
bool bResult[MAX_X][MAX_Y];//用来判断是否已经有值了。




string maxString(string A, string B)
{
	int lenA = A.length();
	int lenB = B.length();
	if (lenA > lenB)
		return A;

	return B;
}

string maxCommonString(string A, string B)
{
	int lenA = A.length();
	int lenB = B.length();

	if (0 == lenA || 0 == lenB)
	{
		return "";
	}

	if (1 == lenA)
	{
		string::size_type idx;
		idx = B.find(A);
		if (idx == string::npos)
		{
			Result[lenA - 1][lenB - 1] = "";
			bResult[lenA - 1][lenB - 1] = true;
		}
		else
		{
			Result[lenA - 1][lenB - 1] = A;
			bResult[lenA - 1][lenB - 1] = true;
		}
		return Result[lenA - 1][lenB - 1];
	}

	if (1 == lenB)
	{
		string::size_type idx;
		idx = A.find(B);
		if (idx == string::npos)
		{
			Result[lenA - 1][lenB - 1] = "";
			bResult[lenA - 1][lenB - 1] = true;
		}
		else
		{
			Result[lenA - 1][lenB - 1] = B;
			bResult[lenA - 1][lenB - 1] = true;
		}

		return Result[lenA - 1][lenB - 1];
	}


	//进入递归。
	if (A[lenA - 1] == B[lenB - 1])
	{
		if (false == bResult[lenA - 2][lenB - 2])
		{
			Result[lenA - 2][lenB - 2] = maxCommonString(A.substr(0, lenA - 1), B.substr(0, lenB - 1));
			bResult[lenA - 2][lenB - 2] = true;
		}

		Result[lenA - 1][lenB - 1] = Result[lenA - 2][lenB - 2] + A[lenA - 1];
		bResult[lenA - 1][lenB - 1] = true;
	}
	else
	{
		if (false == bResult[lenA - 2][lenB - 1])
		{
			Result[lenA - 2][lenB - 1] = maxCommonString(A.substr(0, lenA - 1), B);
			bResult[lenA - 2][lenB - 1] = true;
		}

		if (false == bResult[lenA - 1][lenB - 2])
		{

			Result[lenA - 1][lenB - 2] = maxCommonString(A, B.substr(0, lenB - 1));
			bResult[lenA - 1][lenB - 2] = true;
		}


		Result[lenA - 1][lenB - 1] = maxString(Result[lenA - 1][lenB - 2], Result[lenA - 2][lenB - 1]);
		bResult[lenA - 1][lenB - 1] = true;

	}

	return Result[lenA - 1][lenB - 1];
}




int main()
{

	string t1, t2;
	cin >> t1;
	cin >> t2;
	cout << maxCommonString(t1, t2) << endl;

	return 0;
}

参考资料

https://www.cnblogs.com/fengziwei/p/7827959.html
http://www.cnblogs.com/wangkundentisy/p/9346376.html

你可能感兴趣的:(例题)