1. 程式人生 > >求最長子序列和最長公共子串

求最長子序列和最長公共子串

又有一段時間沒刷題,今天溫故下,最長公共子序列和最長公共子串概念不一樣,子序列可以不連續,子串必須連續,這兩題均可以用動態規劃解決!,下面程式在VS上跑過無問題!

#include<iostream>
#include<string>
#include<algorithm>
#include<cmath>
using namespace std;
 
//動態規劃求最長子序列
int LongestCommonSeq(string s1, string s2)
{
	int m = s1.size()+1;
	int n = s2.size()+1;
	cout << m << n << endl;
	int** dp = (int**)malloc(sizeof(int *)*m);
	for (int i = 0; i <= m; i++)
	{
		dp[i] = (int *)malloc(sizeof(int)*n);
	}
	for (int i = 0; i <= m; i++)
	{
		for (int j = 0; j <= n; j++)
		{
			if (i == 0 || j == 0)
			{
				dp[i][j] = 0;
			}
			else if (s1[i-1] == s2[j-1])
			{
				dp[i][j] = dp[i - 1][j - 1] + 1;
			}
			else
			{
				dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
			}
		}
	}
	return dp[m-1][n-1];
}

//動態規劃求解最長連續子串
string LongConsecStr(string s1, string s2)
{
	int m = s1.size();
	int n = s2.size();
	int index = 0;
	int **dp = (int**)malloc(sizeof(int *)*m);
	for (int i = 0; i <= m; i++)
	{
		dp[i] = (int *)malloc(sizeof(int)*n);
	}
	int max = -1;
	for (int i = 0; i <= m; i++)
	{
		for (int j = 0; j <= n; j++)
		{
			if (i == 0 || j == 0)
			{
				dp[i][j] = 0;
			}
			else if(s1[i - 1] == s2[j - 1])
			{
				dp[i][j] = dp[i - 1][j - 1] + 1;
			}
			else
			{
				dp[i][j] = 0;
			}
			if (max < dp[i][j])
			{
				max = dp[i][j];
				index = i;
			}
		}
	}
	return s1.substr(index - max, index);
}


int main()
{
	string s1 = "ABHDF";
	string s2 = "BCDFG";
	int res1 = LongestCommonSeq(s1, s2);
	string res2 = LongConsecStr(s1, s2);
    cout<< res1<<" "<<res2 << endl;
	return 0;
}