最长公共子串(LCS)的求解

大致概念看链接

最长公共子串的矩阵追踪技术

#include<bits/stdc++.h>
using namespace std;

const int maxn = 100;
int lcs[maxn][maxn];//构建lcs追踪矩阵
string str1,str2;
string ans;

int LCS(int n,int m)
{
	if(n==-1||m==-1)return 0;
	if(str1[n]==str2[m])
	{//需要注意的是并非所有的符号相等都能够被认为是公共子串的一部分 
		lcs[n][m]=0;//nm各-1
		return LCS(n-1,m-1)+1;
	}
	else
	{
		int a = LCS(n,m-1);
		int b = LCS(n-1,m);
		if(a>b)
		{
			lcs[n][m]=1;//等于 LCS(n,m-1) 
			return a;
		}
		else
		{
			lcs[n][m]=-1;//等于LCS(n-1,m)
			return b;
		}
	}
	return 0;
}


int main()
{
	//getline(cin,str1);
	//getline(cin,str2);
	str1="BDCABA";
	str2="ABCBDAB";
	int lenth1 = str1.size();
	int lenth2 = str2.size();
	ans="";//LCS答案
	cout<<LCS(lenth1-1,lenth2-1)<<endl;
	//lcs矩阵 
	for(int i=0;i<lenth1;i++)
	{
		for(int k=0;k<lenth2;k++)
		{
			printf("%3d",lcs[i][k]);
		}
		cout<<endl;
	}
	cout<<"----------------------------"<<endl;
	//lcs追踪 
	int x = lenth1-1;
	int y = lenth2-1;
	while(x>=0&&y>=0)
	{
		int t = lcs[x][y];
		if(!t)
		{//沿追踪路径时相等的字符就是LCS字符串的字符组成
			if(str1[x]==str2[y])ans+=str1[x];
			x--;y--;
		}
		else
		{
			if(t==1)y--;
			if(t==-1)x--;
		}
	}
	//追踪是反向的所以这里需要完成反转
	reverse(ans.begin(),ans.end());
	cout<<ans<<endl;
	return 0;
}

对于程序中的测试样例,我发现公共字符串并不唯一,这与那个链接里的博主得到的答案并不相同。但是经过检验,都是正确答案而已。

OK

猜你喜欢

转载自www.cnblogs.com/savennist/p/13389978.html