HJ65 查找最长公共子串

题目描述

查找两个字符串a,b中的最长公共子串。若有多个,输出在较短串中最先出现的那个。
注:子串的定义:将一个字符串删去前缀和后缀(也可以不删)形成的字符串。请和“子序列”的概念分开!
 
数据范围:字符串长度1\le length \le300 \1length300 
进阶:时间复杂度:O(n^3)\O(n3) ,空间复杂度:O(n)\O(n) 

输入描述:

输入两个字符串

输出描述:

返回重复出现的字符

示例

输入:
abcdefghijklmnop
abcsafjklmnopqrstuvw
输出:
jklmnop

解题思路

通过一个二维数组记录已遍历的匹配的两个字符串的结果(单次字符匹配的结果),数组的两个下标 i 和 j 表示串1前 i 部分和串2前 j 部分匹配的长度。nmax记录目前匹配最长子串的长度,而pos为该子串尾部的位置。

代码如下:

#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

int dp[301][301];
int nmax,pos;

void solve(string a,string b){
    for(int i=0;i<a.length();i++){
        if(a[i] == b[0]){
            dp[i][0] = 1;
            nmax = 1;
            pos = i;
        }else dp[i][0] = 0;
    }
    for(int i=0;i<b.length();i++){
        if(a[0] == b[i]){
            dp[0][i] = 1;
            nmax = 1;
            pos = 0;
        }else dp[0][i] = 0;
    }
    
    for(int i=1;i<a.length();i++){
        for(int j=1;j<b.length();j++){
            if(a[i] == b[j]){
                dp[i][j] = dp[i-1][j-1] + 1;
                if(dp[i][j] > nmax)nmax = dp[i][j],pos = i;
            }
            else dp[i][j] = 0;
        }
    }
    cout<<nmax<<endl;
}
int main(){
    string a,b;
    while(cin>>a>>b){
        nmax = 0;
        if(a.length() > b.length())
            swap(a,b);
        solve(a,b);
    }
    return 0;
}

 

posted @ 2022-08-06 21:18  An2i  阅读(48)  评论(0编辑  收藏  举报