题目:

给定两个字符串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 ;
}

(字符串)最长公共字串(Longest-Common-SubString,LCS)的更多相关文章

  1. 动态规划求最长公共子序列(Longest Common Subsequence, LCS)

    1. 问题描述 子串应该比较好理解,至于什么是子序列,这里给出一个例子:有两个母串 cnblogs belong 比如序列bo, bg, lg在母串cnblogs与belong中都出现过并且出现顺序与 ...

  2. 最长公共子序列(LCS)问题 Longest Common Subsequence 与最长公告字串 longest common substr

    问题描述:字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列.令给定的字符序列X=“x0,x1,…,xm-1”,序列Y=“y0,y1,…,yk ...

  3. 最长公共子串算法(Longest Common Substring)

    给两个字符串,求两个字符串的最长子串 (例如:"abc""xyz"的最长子串为空字符串,"abcde"和"bcde"的最 ...

  4. 动态规划 ---- 最长公共子序列(Longest Common Subsequence, LCS)

    分析: 完整代码: // 最长公共子序列 #include <stdio.h> #include <algorithm> using namespace std; ; char ...

  5. 最长公共子序列与最长公共字串 (dp)转载http://blog.csdn.net/u012102306/article/details/53184446

    1. 问题描述 子串应该比较好理解,至于什么是子序列,这里给出一个例子:有两个母串 cnblogs belong 比如序列bo, bg, lg在母串cnblogs与belong中都出现过并且出现顺序与 ...

  6. URAL 1517 Freedom of Choice(后缀数组,最长公共字串)

    题目 输出最长公共字串 #define maxn 200010 int wa[maxn],wb[maxn],wv[maxn],ws[maxn]; int cmp(int *r,int a,int b, ...

  7. Longest Common Substring($LCS$)

    Longest Common Substring(\(LCS\)) 什么是子序列? 子序列就是某一个序列的不连续的一部分. 如图, \(abcde\)就是图中序列的一个子序列. 公共子序列 公共子序列 ...

  8. 最长公共字串算法, 文本比较算法, longest common subsequence(LCS) algorithm

    ''' merge two configure files, basic file is aFile insert the added content of bFile compare to aFil ...

  9. poj 3080 kmp求解多个字符串的最长公共字串,(数据小,有点小暴力 16ms)

    Blue Jeans Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 14113   Accepted: 6260 Descr ...

随机推荐

  1. JavaScript 继承和数组

    前言 因为篇幅比较短,所以将JavaScript中的继承和数组进行统一写. 继承 当一个函数对象被创建的时候,Function构造器产生的函数对象会运行类似这样的代码: this.prototype ...

  2. URAL 1880 Psych Up's Eigenvalues

    1880. Psych Up's Eigenvalues Time limit: 0.5 secondMemory limit: 64 MB At one of the contests at the ...

  3. linux基础环境部署

    Content 0.序 1.更新安装库 2.安装基础库 0.序 本文主要是记录php在 Centos下的安装配置 .文中如无特别说明.表示php-5.6.31代码目录. 1.更新安装库 $ yum u ...

  4. java值和地址值传递、字符串常量池的理解

    #java值和地址值传递的理解: - 基本数据类型和基本数据类型的封装类都是:值传递    * 形式参数的改变不会影响实际参数的改变(相当于将值复制一份传递给形参,自身没做任何改变)   - 引用数据 ...

  5. Git_创建与合并分支

    在版本回退里,你已经知道,每次提交,Git都把它们串成一条时间线,这条时间线就是一个分支.截止到目前,只有一条时间线,在Git里,这个分支叫主分支,即master分支.HEAD严格来说不是指向提交,而 ...

  6. C++反汇编-菱形继承

    学无止尽,积土成山,积水成渊-<C++反汇编与逆向分析技术揭秘> 读书笔记.马上就要出差了,回来后接着写吧. 一.概述 菱形继承是最复杂的对象结构,菱形结构会将单一继承与多重继承进行组合. ...

  7. Node.js学习笔记(1) - Node.js简介

    近期在看一些Node.js的知识,看完后觉得,一些前面的东西忘记了,于是整理一下,方便自己查阅,也希望对学习Node.js的朋友有些帮助: 当然以下只是我个人的观点和理解,不喜勿喷,也望大神指教. 一 ...

  8. mysql 连接出错 'mysqladmin flush-hosts'

    本文章 转载于: http://blog.itechol.com/space-33-do-blog-id-5670.html    求助QQ:499628121   环境说明:   内网测试服务器19 ...

  9. rocketmq技术架构图

    NameServer.Broker.Producer.Consumer之间如何进行通信,如何工作: NameServer和Broker: NameServer主要做两件事情,第一就是管理Broker, ...

  10. 解决Fragment每次进入都加载的问题

    1.首先了解一下fragment的生命周期 onCreate是指创建该fragment类似于Activity.onCreate,你可以在其中初始化除了view之外的东西,onCreateView是创建 ...