求两个字符串的最长公共子串

/*
算法原理
LCS[i,j]	= 0				(i<0||j<0)
			  LCS(i-1,j-1)	(i>=0 && b>0 && (str1[i]==str2[j]))
(1) 构造一个str1.size()*str2.size()的矩阵vec
(2) 如果 str1[i] == str2[j],则vec[i][j] = vec[i-1][j-1]+1;
*/
string LCS(string const &str1,string const & str2)
{
	if(str1.size()>str2.size())
		return LCS(str2,str1);

	vector<vector<int> > vec;
	vec.resize(str1.size());
	for(int i=0;i<(int)str1.size();++i)
	{
		vec[i].resize(str2.size());
	}

	int iIndex = -1;
	int iMax = 0;
	for(int i = 0;i<(int)str1.size();++i)
	{
		for(int j = 0;j<(int)str2.size();++j)
		{
			if(str1[i] == str2[j])
			{
				int n = 1+((i>0&&j>0)?vec[i-1][j-1]:0);
				vec[i][j] = n;
				if(iMax<n)
				{
					iMax = n;
					iIndex = i;
				}
			}
		}
	}
	if(iIndex == -1)
		return (string());
	return str1.substr(iIndex-iMax+1,iMax);
}


//因为每一次的比较都是只用到第i列的结果,所以我们可以只使用一个一维数组来保存结果即可
string LCSEx(string const &str1,string const & str2)
{
	if(str1.size()>str2.size())
		return LCS(str2,str1);

	vector<int> vec(str2.size());
	int iIndex = -1;
	int iMax = 0;
	for(int i = 0;i<(int)str1.size();++i)
	{
		for(int j = (int)str2.size()-1;j>=0;--j)
		{
			if(str1[i] == str2[j])
			{
				int n = 1+(j>0?vec[j-1]:0);
				vec [j] = n;
				if(iMax<n)
				{
					iMax = n;
					iIndex = i;
				}
			}
			else
			{
				vec[j] = 0;
			}
		}
	}
	if(iIndex == -1)
		return (string());
	return str1.substr(iIndex-iMax+1,iMax);
}

posted on 2010-09-28 15:49  SammyLan  阅读(2130)  评论(0编辑  收藏  举报

导航