【动态规划】LCS算法:求两字符串最大公共字符串(连续)
2016-08-12 12:46
411 查看
LCS算法的应用
问题描述:求两字符串的连续最大公共子字符串
思路:根据上文LCS算法求解两字符串的最大公共子序列(不连续),可以得到求解连续子字符串的启示,如图所示,构造LCS矩阵vec,将两个字符串按矩阵方式排开,矩阵中的每个元素vec[i][j]表示字符串a的第i个字符和字符串b的第j个字符是否相等。如图1中所示。在斜对角线上,连续的1就表示两字符串对应位置连续相等。
![](https://oscdn.geek-share.com/Uploads/Images/Content/202011/18/30bf46af71059479c54f59944a2775e3)
最长的连续1就表示该子字符串是最大公共子字符串。分别找出对应的字符即可求出这个最长子串。如下图1,有两个最长的公共子字符串。bab与aba.
我们可以对这个算法进行改进,当前行列相等时,在其左上角值的基础上+1,这样就记录了连续1的长度,如下图2
![](https://oscdn.geek-share.com/Uploads/Images/Content/202011/18/57b8191dce1cbee1d1dbda3098ff6d6c)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202011/18/4f2798ed28b7a227fbde5042db324372)
再对算法进行改进,可以发现,我们只需要知道最大值就知道最大公共子串的长度,而最大值的位置可以求出最大公共子串的结束位置,而求解这两个信息,使用一个矩阵是十分浪费空间的!实际上只需要一维数组即可解决,在求当前行时,记录上一行的值,并始终保存最大值所在的位置(行或列),就可以求出结果。
代码如下:
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
问题描述:求两字符串的连续最大公共子字符串
思路:根据上文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
相关文章推荐
- 【动态规划】LCS算法:求两字符串最大公共子序列/删除字符使成为回文串
- LCS算法寻找字符串最大公共子串
- LCS求两个字符串的最大公共子串
- 两个或N个字符串最大公共子串算法
- 数组字符串那些经典算法:最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串
- LCS 最大公共序列算法
- 实现简易字符串压缩算法:一个长度最大为128的字符串, 由字母a-z或者A-Z组成,将其中连续出现2次以上(含2次)的字母转换为字母和出现次数,以达到压缩目的
- 最大公共连续子串(LCS问题)
- 数组字符串那些经典算法:最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串 (转)
- 算法之插入、归并排序,最大公共子串lcs
- ] 找工作知识储备(2)---数组字符串那些经典算法:最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串
- 面试的算法1(C语言)(整理)(组合数 字符串倒置 最大公共串)
- 两个或N个字符串最大公共子串算法
- 相似度算法(二)-------最大公共字符串
- 利用后缀数组求字符串的最长重复子串的算法 利用二维数组求两个字符串的最长公共字串(动态规划)
- [算法]求最大公共子项(LCS)
- 两个或N个字符串最大公共子串算法
- 找工作知识储备(2)---数组字符串那些经典算法:最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串
- 找工作知识储备---数组字符串那些经典算法:最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串
- 算法题-两个字符串的最大公共子串