您的位置:首页 > 编程语言 > C语言/C++

【动态规划】LCS算法:求两字符串最大公共字符串(连续)

2016-08-12 12:46 411 查看
LCS算法的应用

问题描述:求两字符串的连续最大公共子字符串

思路:根据上文LCS算法求解两字符串的最大公共子序列(不连续),可以得到求解连续子字符串的启示,如图所示,构造LCS矩阵vec,将两个字符串按矩阵方式排开,矩阵中的每个元素vec[i][j]表示字符串a的第i个字符和字符串b的第j个字符是否相等。如图1中所示。在斜对角线上,连续的1就表示两字符串对应位置连续相等。



最长的连续1就表示该子字符串是最大公共子字符串。分别找出对应的字符即可求出这个最长子串。如下图1,有两个最长的公共子字符串。bab与aba.

我们可以对这个算法进行改进,当前行列相等时,在其左上角值的基础上+1,这样就记录了连续1的长度,如下图2


 


再对算法进行改进,可以发现,我们只需要知道最大值就知道最大公共子串的长度,而最大值的位置可以求出最大公共子串的结束位置,而求解这两个信息,使用一个矩阵是十分浪费空间的!实际上只需要一维数组即可解决,在求当前行时,记录上一行的值,并始终保存最大值所在的位置(行或列),就可以求出结果。

代码如下:
string LCS_continuous(string str1,string str2)
{
int i,j,maxnum=0,maxj=0;
int n1=str1.size(),n2=str2.size();
vector<int> last,cur,temp;//last、cur记录上一行、当前行的LCS信息,temp作为辅助数组。
for(i=0;i<n2+1;i++)//初始值:第0行第0列置0
{
last.push_back(0);
cur.push_back(0);
}
temp=cur;
for(i=1;i<=n1;i++)
{
cur=temp;//cur清零
for(j=1;j<=n2;j++)
{
if(str1[i-1]==str2[j-1])
{
cur[j]=last[j-1]+1;
if(cur[j]>maxnum)//更新最大值
{
maxnum=cur[j];
maxj=j-1;//记录最大值列号
}
}
}
last=cur;//把当前行信息传递给last
}
return str2.substr(maxj-maxnum+1,maxnum);
}相关参考: http://blog.csdn.net/yebanxin/article/details/52186706 http://www.2cto.com/kf/201410/346523.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐