区别:
最长公共子串要求在原字符串中是连续的,而子序列只需要保持相对顺序一致,并不要求连续。
最长公共子串
描述
有两个字符串(可能包含空格),请找出其中最长的公共连续子串,输出其长度。
例如:
输入: abcde bcd
输出: 3
代码
暴力法
public int getLCS(String s, String t){
if(s == null || t == null){
return 0;
}
int l1 = s.length();
int l2 = t.length();
for(int i = 0; i < l1; i++){
for(int j = 0; j < l2; j++){
int m = i;
int k = j;
int len = 0;
while(m < l1 && k < l2 && s.charAt(m) == t.charAt(k)){
len++;
m++;
k++;
}
res = Math.max(res, len);
}
}
return res;
}
def LCSstring(str1, str2):
if not str1 or not str2:
return 0
m = len(str1)
n = len(str2)
res = 0
for i in range(m):
for j in range(n):
l = i
k = j
length = 0
while l < m and k < n and str1[l] == str2[k]:
length += 1
l += 1
k += 1
res = max(res, length)
return res
/*02-求最长公共子串*/
#include <iostream>
using namespace std;
//暴力求解
string getLCS(const string &str1,const string &str2)
{
//记录最长子串在str1中的起始位置和长度
size_t max_start = 0,max_len = 0;
for(size_t i=0;i<str1.length();i++){
for(size_t j=0;j<str2.length();j++){
//计算当前最长公共子串
size_t k,l;
for(k=i,l=j;k<str1.length()&&l<str2.length();k++,l++){
if(str1.at(k)!=str2.at(l))
break;
}
//记录最长长度的公共子串
if(k-i>max_len){
max_len = k-i;
max_start = i;
}
}
}
return str1.substr(max_start,max_len);
}
//矩阵法求解
string getLCS1(const string &str1,const string &str2)
{
//记录最长子串在str1中的结束位置和长度
int max_end = 0,max_len = 0;
//创建比较矩阵
int **arr = new int *[str1.length()];
for(size_t i=0;i<str1.length();i++){
arr[i] = new int[str2.length()];
for(size_t j=0;j<str2.length();j++){
//比较字符,将比较结果写入矩阵
if(str1.at(i)==str2.at(j)){//赋值 左上角+1
//如果左上角不存在
if(i==0||j==0)
arr[i][j] = 1;
else
arr[i][j] = arr[i-1][j-1]+1;
//记录最长长度和此时str1中最后一个字符的位置
if(arr[i][j]>max_len){
max_len = arr[i][j];
max_end = i;
}
}
else{
arr[i][j] = 0;
}
}
}
//释放空间
for(size_t i=0;i<str1.length();i++){
delete[] arr[i];
}
delete[] arr;
//返回最长公共子串
return str1.substr(max_end-max_len+1,max_len);
}
int main()
{
string str1 = "kkkhellowebyebye";
string str2 = "ghsasabyehellod";
cout<<getLCS(str1,str2)<<endl;
cout<<getLCS1(str1,str2)<<endl;
return 0;
}