最长公共子串(LCS)

找两个字符串的最长公共子串,这个子串要求在原字符串中是连续的。其实这又是一个序贯决策问题,可以用动态规划来求解。我们采用一个二维矩阵来记录中间的结果。这个二维矩阵怎么构造呢?直接举个例子吧:"bab"和"caba"(当然我们现在一眼就可以看出来最长公共子串是"ba"或"ab")

   b  a  b

c  0  0  0

a  0  1  0

b  1  0  1

a  0  1  0

我们看矩阵的斜对角线最长的那个就能找出最长公共子串。

不过在二维矩阵上找最长的由1组成的斜对角线也是件麻烦费时的事,下面改进:当要在矩阵是填1时让它等于其左上角元素加1。

   b  a  b

c  0  0  0

a  0  1  0

b  1  0  2

a  0  2  0

这样矩阵中的最大元素就是 最长公共子串的长度。

在构造这个二维矩阵的过程中由于得出矩阵的某一行后其上一行就没用了,所以实际上在程序中可以用一维数组来代替这个矩阵。

void GetMaxlenChildStr(char* str1,int n1,char* str2,int n2,char* res)
{
	int max=0;                        //矩阵元素中的最大值
	int *pre=new int[n2];     //保存矩阵的上一行
	int *cur=new int[n2];     //当前行
	for (int i=0;i<n2;i++)     //初始化
	{
		pre[i]=0;
	}
	for (int i=0;i<n2;i++)
	{
		cur[i]=0;
	}
   int pos=0;                      //矩阵元素最大值出现在第几列
   for (int i=0;i<n1;i++)
   {
	   for (int j=0;j<n2;j++)
	   {
              if (str1[i]==str2[j])
              {
				  if (j==0)
				  {
                     cur[j]=1;
				  }
				  else
				  {
                      cur[j]=pre[j-1]+1;
				  }
				  if (cur[j]>max)
				  {
					  max=cur[j];
					  pos=j;
				  }
              }
	   }
     for (int i=0;i<n2;i++)
     {
         pre[i]=cur[i];
     }
   }
    strncpy(res,str2+pos-max+1,max);
}
int main()
{
        char str2[]="aba";
	char str1[]="cabda";
	char  res[5]={'\0'};
        GetMaxlenChildStr(str1,5,str2,3,res);
	return 0;
}

http://www.cnblogs.com/zhangchaoyang/articles/2012070.html#3022705

时间: 2024-10-06 07:03:49

最长公共子串(LCS)的相关文章

算法作业6 动态规划 - 最长公共子串问题

问题描述:Given 2 sequences, X = x1,...,xm and Y = y1,...,yn, find a common subsequence whose length is maximum. Subsequence need not be consecutive, but must be in order. 程序思路: 使用递归的思路可以解决这个问题.设输入的两个子串为X[0…m - 1]和Y[0…n - 1],L(X[0…m - 1], Y[0…n - 1])为X和Y的

最长公共子串_暴力解法(不会正解)

最长公共子串 lcs.cpp/.in/.out 计算两个字符串的最大公共子串(Longest Common Substring)的长度,字符不区分大小写,这里的最大公共子串要求的字串是连续的. 输入: 两行,每行一个字符串,字符串长度<=1000. 输出: 输出一个整数,表示公共子串的长度. 样例输入: asdfas werasdfaswer 样例输出: 6 下面上代码: 1 #include<bits/stdc++.h> 2 using namespace std; 3 char o[

【实习记】2014-08-29算法学习Boyer-Moore和最长公共子串(LCS)

昨天的问题方案一:寻找hash函数,可行性极低.方案二:载入内存,维护成一个守护进程的服务.难度比较大.方案三:使用前5位来索引,由前3位增至前5位唯一性,理论上是分拆记录扩大100倍,但可以就地利用mysql,最易行.方案四:使用方案三,但增加一个表以减少冗余,但代价新开一个表,并且每次查询都select join两个表. 研究了 求最长公共子串问题,顺便研究了字符串匹配 字符串匹配的Boyer-Moore算法http://www.ruanyifeng.com/blog/2013/05/boy

动态规划算法之:最长公共子序列 & 最长公共子串(LCS)

1.先科普下最长公共子序列 & 最长公共子串的区别: 找两个字符串的最长公共子串,这个子串要求在原字符串中是连续的.而最长公共子序列则并不要求连续. 2.最长公共子串 其实这是一个序贯决策问题,可以用动态规划来求解.我们采用一个二维矩阵来记录中间的结果.这个二维矩阵怎么构造呢?直接举个例子吧:"bab"和"caba"(当然我们现在一眼就可以看出来最长公共子串是"ba"或"ab") b a b c 0 0 0 a 0 1

UVa 10192 - Vacation ( LCS 最长公共子串)

链接:UVa 10192 题意:给定两个字符串,求最长公共子串的长度 思路:这个事最长公共子串的直接应用 #include<stdio.h> #include<string.h> int max(int a,int b) { return a>b?a:b; } int main() { char s[105],t[105]; int i,j,k=0,m,n,dp[105][105]; while(gets(s)!=NULL){ if(strcmp(s,"#"

《算法导论》读书笔记之动态规划—最长公共子序列 &amp; 最长公共子串(LCS)

From:http://my.oschina.net/leejun2005/blog/117167 1.先科普下最长公共子序列 & 最长公共子串的区别: 找两个字符串的最长公共子串,这个子串要求在原字符串中是连续的.而最长公共子序列则并不要求连续. 2.最长公共子串 其实这是一个序贯决策问题,可以用动态规划来求解.我们采用一个二维矩阵来记录中间的结果.这个二维矩阵怎么构造呢?直接举个例子吧:"bab"和"caba"(当然我们现在一眼就可以看出来最长公共子串是

算法设计 - LCS 最长公共子序列&amp;&amp;最长公共子串 &amp;&amp;LIS 最长递增子序列

出处 http://segmentfault.com/blog/exploring/ 本章讲解:1. LCS(最长公共子序列)O(n^2)的时间复杂度,O(n^2)的空间复杂度:2. 与之类似但不同的最长公共子串方法.最长公共子串用动态规划可实现O(n^2)的时间复杂度,O(n^2)的空间复杂度:还可以进一步优化,用后缀数组的方法优化成线性时间O(nlogn):空间也可以用其他方法优化成线性.3.LIS(最长递增序列)DP方法可实现O(n^2)的时间复杂度,进一步优化最佳可达到O(nlogn)

动态规划 &amp; 最长公共子串算法(LCS)

求最长公共子串可以先求最长公共子串的长度,并且记录那些公共子串字符的长度以及字符,然后通过回溯可以找到所有的公共子串. 下面是求最长公共子串长度的动态规划方法. 1:决策,我们在最后一步需要做的决策是,是否要将A[n],B[m]加入公共子串序列中. 2:由 1 可知,若以DP[i][j]表示A[1..i] 与 B[1..j]的最长公共子串的长度,那么可以得到 (1) 若A[i] == B[j]  (即作出决策,将A[i],B[i]都加入公共子串) DP[i][j] = DP[i - 1][j -

最长公共子串

(连续) - 阿里笔试[分析+编码] 题目描述:给定一个query和一个text,均由小写字母组成.要求在text中找出以同样的顺序连续出现在query中的最长连续字母序列的长度.例如,query为“acbac”,text为“acaccbabb”,那么text中的“cba”为最长的连续出现在query中的字母序列,因此,返回结果应该为其长度3.请注意程序效率. [思路]用一个矩阵来记录两个字符串中所有位置的两个字符之间的匹配情况,若是匹配则为1,否则为0.然后求出对角线最长的1序列,其对应的位置