题目:

给定两个字符串X,Y,求二者最长的公共子串,例如X=[aaaba],Y=[abaa]。二者的最长公共子串为[aba],长度为3。

子序列是不要求连续的,字串必须是连续的。

思路与代码:

1、简单思想:

  • 遍历两个字符串X、Y,分别比较X的字串与Y的字串,求出最长的公共字串。
  • 设X长度为m,Y长度为n,最长公共字串长度为len,则时间复杂度为O(m*n*len),空间复杂度为O(1)
#include <iostream>
#include <vector> using namespace std; int getComLen(char *str1,char *str2){
int len=;
while(*str1 && *str2){
if(*(str1++)==*(str2++))
len++;
}
return len;
} int LCS1(char *str1,int len1,char *str2,int len2){
int maxlen=; // max length of LCS
int maxIndex=; // start position of LCS
int len;
for(int i=;i<len1;i++){
for(int j=;j<len2;j++){
len=getComLen(str1+i,str2+j);
if(len>maxlen){
maxlen=len;
maxIndex=i;
}
}
}
cout<<"Length of Longest Common Substring: "<<maxlen<<endl;
cout<<"LCS is: ";
for(int i=maxIndex;i<maxIndex+maxlen;i++)
cout<<str1[i];
cout<<endl;
return maxlen;
}
int main()
{
char str1[]="Chinese";
char str2[]="Chienglish";
int len1=sizeof(str1)/sizeof(str1[])-;
int len2=sizeof(str2)/sizeof(str2[])-;
cout << LCS1(str1,len1,str2,len2) << endl;
return ;
}

2、动态规划思想:

  • 与最长字符子序列一样,最长字符字串一样可以通过动态规划来求解,不一样的是,字串是连续的。
  • 假设dp[i][j]来表示以x[i]、y[j]结尾的公共子串长度(不是最长,最长的字串长度需要通过比较得到),由于字串连续,x[i]和y[i]要么与前面的前面的公共字串构成新的字串,要么不能构成公共字串。
  • 公共字串长度的状态转移方程如下:

初始状态:dp[i][j]=0 if i==0 || j==0

转移方程:dp[i][j] = dp[i-1][j-1]+1 if x[i-1]==y[j-1]

dp[i][j] = 0 if x[i-1]!=y[j-1]

  • 最长公共字串长度以及最长公共字串,需要在求公共字串长度的过程中通过比较并记录下来,具体参考代码。
  • 设X长度为m,Y长度为n,最长公共字串长度为len,则时间复杂度为O(m*n),空间复杂度为O(m*n)
#include <iostream>
#include <vector> using namespace std; // dynamic programming
int LCS2(char *str1,int len1,char *str2,int len2){
vector<vector<int> > dp(len1+,vector<int>(len2+,));
int maxlen=; // max length of LCS
int maxIndex=; // start position of LCS
for(int i=;i<=len1;i++){
for(int j=;j<=len2;j++){
if(i== || j==)
dp[i][j]=;
else{
if(str1[i-]==str2[j-])
dp[i][j]=dp[i-][j-]+;
} if(dp[i][j]>maxlen){
maxlen=dp[i][j];
maxIndex=i-maxlen+;
}
}
}
cout<<"Length of Longest Common Substring: "<<maxlen<<endl;
cout<<"LCS is: ";
for(int i=maxIndex-;i<maxIndex-+maxlen;i++)
cout<<str1[i];
cout<<endl;
return maxlen;
} int main()
{
char str1[]="Chinese";
char str2[]="Chienglish";
int len1=sizeof(str1)/sizeof(str1[])-;
int len2=sizeof(str2)/sizeof(str2[])-;
cout << LCS2(str1,len1,str2,len2) << endl;
return ;
}

最新文章

  1. (转)Nginx SSL+tomcat集群,request.getScheme() 取到https正确的协议
  2. 为什么要放弃使用Thread.Sleep
  3. 对Object类中方法的深入理解
  4. Linux内核分析第三周学习总结:构造一个简单的Linux系统MenuOS
  5. linux-5重要进程守护
  6. PLSQL导入Excel数据方法
  7. KPROCESS IDT PEB Ldr 《寒江独钓》内核学习笔记(3)
  8. Complete the Sequence[HDU1121]
  9. iOS 数字字符串的直接运算 + - * /
  10. shell 流程控制
  11. 一个消除if语句的例子
  12. winform程序中Label自动换行
  13. IT第二十一天 - Collections、ArrayList集合、LinkedList集合、Set集合、HashMap集合、集合的操作注意【修20130828】
  14. 如何自定义JSR-303标准的validator
  15. 201521123018 《Java程序设计》第6周学习总结
  16. 《ActiveMQ in Action》【PDF】下载
  17. 赛博杯-HMI流水灯-stack
  18. 打包volley
  19. 20 KMP匹配的Next值和Nextval值
  20. phpstorm破解方法

热门文章

  1. 【Codeforces528D】Fuzzy Search FFT
  2. Py脚本运行后暂停不退出
  3. elasticsearch实例讲解增删改查
  4. 分布式文件系统 ~MogileFS~
  5. 正确率、召回率和F值
  6. Make a DAC with a microcontroller&#39;s PWM timer
  7. erlang debug
  8. ASP.NET web.config中&lt;customErrors&gt;节点说明
  9. Asp.net MVC Request Life Cycle
  10. C#程序集系列10,强名称程序集