算法-二分法查找最长公共字串

105 阅读1分钟

区别:

最长公共子串要求在原字符串中是连续的,而子序列只需要保持相对顺序一致,并不要求连续。

最长公共子串

描述

有两个字符串(可能包含空格),请找出其中最长的公共连续子串,输出其长度。

例如:

输入: 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;
}
​
​
​