首页 > 试题广场 >

最长公共连续子串

[编程题]最长公共连续子串
  • 热度指数:6604 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
牛牛有两个字符串(可能包含空格),牛牛想找出其中最长的公共连续子串,希望你能帮助他,并输出其长度。

输入描述:
输入为两行字符串(可能包含空格),长度均小于等于50.


输出描述:
输出为一个整数,表示最长公共连续子串的长度。
示例1

输入

abcde
abgde

输出

2
#include <iostream>
using namespace std;
 
/*思路:假设两个字符串str1和str2,长度分别为m和n,则构建一个m*n的矩阵matrix,
       matrix[i][j]==1表示字符串str1中第i个字符与str2中第j个字符相等,为0则不相等。
       统计矩阵matrix中每条斜线上1的连续最大个数就是str1和str2中公共连续子串的最大长度*/
/*例如:str1: abcde    str2: abgde 
      matrix = [ 1  0  0  0  0 
                 0  1  0  0  0
                 0  0  0  0  0
                 0  0  0  1  0
                 0  0  0  0  1 ]
    斜线上连续的1的最大个数为2,所以最长公共连续子串长度为2*/
 
intmain()
{
    charstr1[51];
    charstr2[51];
    intleng, maxleng=0;
    cin.getline(str1, 51);
    cin.getline(str2, 51);
    intmatrix[50][50] = { 0};              //构建初始矩阵matrix
 
    for(inti = 0; str1[i] != '\0'; i++)            
    {
        for(intj = 0; str2[j] != '\0'; j++)
        {
            if(str1[i] == str2[j])
                matrix[i][j] = 1;                     //如果str1中第i个字符与str2中第j个字符相等,则为1
        }
    }
 
    //循环统计每条斜线上的连续1的个数
    for(inti = 0; str1[i]!='\0'; i++)          
    {
        for(intj = 0; str2[j]!='\0'; j++)
        {
            leng = 0;
            intm = i;
            intn = j;
            while(matrix[m++][n++] == 1)          //判断其右下角位置是否为1
                leng++;
            if(maxleng < leng)
                maxleng = leng;
        }
    }
    cout << maxleng;
         
    return0;
}

发表于 2017-03-27 17:20:26 回复(5)
#include <stdio.h>
#include <string.h>
#define N 50
int main(){
    char s1[N],s2[N];
    int dp[N][N],i,j,max_len=0;
    gets(s1);
    gets(s2);
    for(i=0;i<strlen(s1);i++){
    	for(j=0;j<strlen(s2);j++){
    		if(s1[i]==s2[j]){
		    	if(i>0&&j>0){
	    			dp[i][j]=dp[i-1][j-1]+1;
	    		}else{
		    		dp[i][j]=1;
		    	}
		    	if(max_len<dp[i][j]){
	    			max_len=dp[i][j];
	    		}
		    }
	    }
    }
    printf("%d\n",max_len);
	return 0;
} 

发表于 2017-04-09 19:51:52 回复(0)
import java.util.Scanner;

public class Main 
{
	
	public static void main(String[] args) 
	{
		Scanner scanner = new Scanner(System.in);
		String str1 = scanner.nextLine();
		String str2 = scanner.nextLine();
		scanner.close();
		
		//字符串的长度
		int n1 = str1.length();
		int n2 = str2.length();
		
		//边界情况
		if(n1 < 1 || n2 < 1)
		{
			System.out.println(0);
			return;
		}
		//利用空间存储两个串的比较结果,空间换时间
		int temp[][] = new int[n1][n2];
		//表示最长的公共字串的变量
		int longest = 0;
		char[] char1 = str1.toCharArray();
		char[] char2 = str2.toCharArray();
		
		//初始化数组temp
		for(int i = 0; i < n1; i++)
		{
			for(int j = 0;j <n2;j++)
			{
				temp[i][j] = 0;
			}
		}
		
		//初始化第一行,初始化第一列,因为状态转移公式:item[i][j]=1 +item[i-1][j-1]
		for(int i = 0;i < n1;i++)
		{
			if(char1[i] == char2[0])
				temp[i][0] = 1;
		}
		
		for(int i = 0;i < n2;i++)
		{
			if(char1[0] == char2[i])
				temp[0][i] = 1;
		}
		
		
		//利用状态转移方程进行填充temp二维数组
		for(int i = 1; i < n1;i++)
		{
			for(int j = 1; j<n2;j++)
			{
				if (char1[i] == char2[j]) 
				{
					temp[i][j] = temp[i-1][j-1] +1;
				}
			}
		}
		
		for(int i = 0; i < n1;i++)
		{
			for(int j = 0; j<n2;j++)
			{
				if(temp[i][j] > longest)
					longest = temp[i][j];
			}
		}
		
		System.out.println(longest);
	}
}


发表于 2017-03-24 19:02:57 回复(0)
importjava.util.Scanner;
 
public classMain {
    publicstaticvoidmain(String[] args) {
 
        Scanner scanner=newScanner(System.in);
        String str1=scanner.nextLine();
        String str2=scanner.nextLine();
        intmax=0;
        for(inti=1;i<=str1.length();i++){          
            for(intj=i;j<=str1.length();j++){
                StringBuffer sBuffer=newStringBuffer(str1.substring(i-1, i));
                StringBuffer sBuffer1=newStringBuffer(str1.substring(i, j));
                sBuffer.append(sBuffer1);
                if(str2.contains(sBuffer)){
                    if(sBuffer.length()>=max){
                        max=sBuffer.length();
                    }
                }
            }      
        }
        System.out.println(max);
    }
}
发表于 2017-03-24 15:21:18 回复(3)
import java.util.Scanner;
public class Main{
    public static void main(String[] args){
        Scanner sc=new Scanner(System.in);
        String str1=sc.nextLine();
        String str2=sc.nextLine();
        int len1=str1.length();
        int len2=str2.length();
        char[] char1 = str1.toCharArray();
        char[] char2 = str2.toCharArray();
        int[][] a=new int[len1][len2];
        for(int i=0;i<len1;i++)
        {
            for(int j=0;j<len2;j++)
            {
                if(char1[i]==char2[j])
                {
                    if(i>0&&j>0){
                    a[i][j]=a[i-1][j-1]+1;  //连续公共字符串 
                    }else{
                        a[i][j]=1;
                    }   
                }
            }
        }
        int max=0;
        for(int i=0;i<len1;i++)
        {
            for(int j=0;j<len2;j++){
                if(a[i][j]>max){
                    max=a[i][j];   //获取二维矩阵的最大值
                }
            }
        }
        System.out.print(max);
    }
}
发表于 2017-03-24 22:33:58 回复(0)
import sys
s1=sys.stdin.readline().strip()
s2=sys.stdin.readline().strip()
m,n=len(s1),len(s2)
if m==0 or n==0:
    print(0)
dp=[[0]*(n+1) for i in range(m+1)]
maxnum=0
for i in range(1,m+1):
    for j in range(1,n+1):
        if s1[i-1]==s2[j-1]:
            dp[i][j]=dp[i-1][j-1]+1
            if dp[i][j]>maxnum:
                maxnum=dp[i][j]
print(maxnum)
发表于 2018-05-16 15:36:03 回复(0)
#include<iostream>
#include <string.h>
using namespace std;

int getMax(int a,int b)
{
    return a>b?a:b;
}

int main()
{
    int ret = 0;
    char ch1[50];
    char ch2[50];
    cin.getline(ch1,50);
    cin.getline(ch2,50);
    
    for(int i = 0;i<strlen(ch1);i++)
    {
        int n = 0;
        for(int j =0;j<strlen(ch2);j++)
        {
            if(ch1[i+n] == ch2[j])
            {
                n++;
                ret = getMax(ret,n);
                continue;
            }
            else
                n=0;
        }
        
    }
    
    cout << ret;
}

发表于 2017-09-01 09:11:18 回复(0)
二维动态规划,改成一维了,假设已经找到最长公共子串,并且子串最后一个字符对应于
s1、s2的第i、j个字符,那么dp[i][j]就是最终结果。
dp[i][j]表示以s1第i个字符、s2第j个字符为结尾的最长公共子串长度,
dp[i][j] = dp[i-1][j-1] + k(if(s[i] == s[j],k = 1否则k = 0)
缩小空间复杂度的一种简单方法是dp[i%2][j] = dp[(i-1)%2][j],直接写成二维的程序
然后无脑加上模运算
import java.util.*;
public class Main{
	public static void main(String[] arg){
		 Scanner sc = new Scanner(System.in);
	     char[] s1 = sc.nextLine().toCharArray(), s2 = sc.nextLine().toCharArray();
	     int max = 0;
	     int[] dp = new int[s2.length+1];
	     dp[0] = 0;
	     for(int i = 0; i < s1.length; ++i){
	    	 for(int j = dp.length-1; j >= 1; --j){
	    		 if(s1[i] == s2[j-1])	dp[j] = dp[j-1] + 1;
	    		 else	dp[j] = 0;
	    		 if(dp[j]> max)	max = dp[j];
	    	 }
	     }
	     System.out.println(max);
	}
}

编辑于 2017-08-31 16:35:38 回复(0)
a=raw_input()
b=raw_input()
ct=[]
s=0
fl=0
iflen(a)==1and len(b)!=1:
    fl=1
    fori in b:
        ifa==i:
            print 1
        else:
            print 0
iflen(b)==1:
    fl=1
    fori in a:
        ifb==i:
            print 1
        else:
            print 0   
 
fori in range(len(a)-1):   
    forj in range(len(b)-1):       
        ifa[i]==b[j] and a[i+1]==b[j+1]:
            s=s+1
            break
        elif a[i]==b[j]:
            ct.append(s)
            s=0
ct.append(s)
ifmax(ct)!=0:
     
    print max(ct)+1
else:
    iffl==0:
        print 0

编辑于 2017-03-25 13:24:47 回复(0)
#include<iostream>
#include<string>
using namespace std;
intmain()
{
    intdp[50][50] = {0};
    string input1;
    string input2;
    getline(cin, input1);
    getline(cin, input2);
    intlen1 = input1.size();
    intlen2 = input2.size();
    for(inti = 0; i < len1; ++i)
    {
        for(intj = 0; j < len2; ++j)
        {
            if(input1[i] == input2[j])
            {
                if(i == 0|| j == 0)
                    dp[i][j] = 1;
                else
                    dp[i][j] = 1+ dp[i - 1][j - 1];
            }
            else
                dp[i][j] = 0;
        }
    }
    inttemp = 0;
    for(inti = 0; i < len1; ++i)
    {
        for(intj = 0; j < len2; ++j)
        {
            if(temp < dp[i][j])
                temp = dp[i][j];
        }
    }
    cout << temp << endl;
    return0;
}

发表于 2017-03-25 10:25:46 回复(0)
import java.util.Scanner;

public class LongestSubstring {
	public static void main (String args[]){
		Scanner scanner=new Scanner(System.in);
		String str1=scanner.nextLine();
		String str2=scanner.nextLine();
		int max=0;
		System.out.print(longestSubstring(str1,str2));
	}
	public static int longestSubstring(String str1,String str2){
		if(str1.length()==0||str2.length()==0) return 0;
		int max=0;
		for(int i=1;i<=str1.length();i++){
			for(int j=i;j<=str1.length();j++){
				StringBuffer sb1=new StringBuffer(str1.substring(i-1,j));
				System.out.println(sb1);
				if(str2.contains(sb1)){
					if(sb1.length()>=max) max=sb1.length();
				}

			}
		}
		return max;
	}

发表于 2017-03-28 14:40:34 回复(0)
import java.util.Scanner;

public class Main {
    public int findLength(String s1, String s2) {
        char[] A = s1.toCharArray();
        char[] B = s2.toCharArray();
        int n = A.length;
        int m = B.length;
        int[][] dp = new int[n + 1][m + 1];
        int res = 0;
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                if (A[i - 1] == B[j - 1]) {
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                    res = Math.max(res, dp[i][j]);
                }
            }
        }
        return res;
    }
    public static void main(String[] args) {
        Scanner cin = new Scanner(System.in);
        String s1=cin.nextLine();
        String s2 = cin.nextLine();
        System.out.println(new Main().findLength(s1,s2));
    }
}
/*
abcde
abgde
2

asdfas
werasdfaswer
 6
 */


发表于 2020-06-16 12:41:43 回复(0)
import sys
 
try:
    while True:
        a = input()
        b = input()
        lm = len(a)
        ln = len(b)
        if lm >= ln:
            m = b
            n = a
            l = ln
        else:
            m = a
            n = b
            l = lm
        x = 0
        y = 0
        for i in range(l):
            for j in range(l,i,-1):
                if m[i:j] in n:
                    y = len(m[i:j])
                    break
            if x < y:
                x = y
        print(x)
except:
    pass

发表于 2020-03-19 22:31:41 回复(0)
最长公共连续子串
定义N*N的数组,存储字符串相等的长度
a[ i ][ j ] = a[ i-1 ][ j-1 ] + 1         i>0 && j>0
                1                              else
#include <iostream>
#include <cstring>

using namespace std;
#define N 50
int main(){
    char s1[N];    char s2[N];
    cin.getline(s1, N);
    cin.getline(s2, N);
    int a[N][N];
    int max=0;
    for(int i=0;i<strlen(s1);i++){
        for(int j=0;j<strlen(s2);j++){
            a[i][j]=0;
            if(s1[i]==s2[j]){
                if(i>0&&j>0)a[i][j]=a[i-1][j-1]+1;
                else a[i][j]=1;
                max=max>a[i][j]?max:a[i][j];             }         }     }     cout<<max<<endl;
       return 0;
} 

发表于 2019-07-28 20:45:50 回复(0)
list1=list(input())
list2=list(input())
list1_tmp=[]
list2_tmp=[]
for i in range(len(list1)):
    tmp=""
    for j in range(i,len(list1)):
        tmp=tmp+list1[j]
        list1_tmp.append(tmp)
for i in range(len(list2)):
    tmp=""
    for j in range(i,len(list2)):
        tmp=tmp+list2[j]
        list2_tmp.append(tmp)
L=[]
for i in list1_tmp:
    if i in list2_tmp:
        if len(i)>len(L):
            L=i
print(len(L))

Python暴力枚举子集寻找最长公共子集
编辑于 2018-08-08 22:49:16 回复(0)
还是python简单
s1,s2=input(),input()
lists=[s1[i:i+j+1] forj inrange(len(s1)) fori inrange(len(s1)-j)][::-1]
fori inlists:
    ifs2.count(i)>0:
        print(len(i))
        break
else: print(0)

发表于 2018-07-19 00:50:55 回复(0)
import sys
lines1 = raw_input()
line2 = raw_input()
lines = [lines1,line2]
length1 = len(lines[0])
length2 = len(lines[1])
matrix = [[0]* length2 for i in range(length1)]
for i in range(len(lines[0])):
    for j in range(len(lines[1])):
        if lines[0][i] == lines[1][j]:
            matrix[i][j] = 1
maxCount = 0
for i in range(len(lines[0])):
    for j in range(len(lines[1])):
        count = 0
        while  i < len(lines[0]) and j < len(lines[1]) and matrix[i][j] == 1:
            count += 1
            i += 1
            j += 1
        maxCount = max(maxCount,count)
print maxCount

发表于 2018-04-19 09:12:28 回复(0)

 #include <iostream> #include <string.h>  using namespace std; int dp[50][50]={0}; int LCS2(const string &a,const string &b,int n,int m)
{
    memset(dp[0],0,sizeof(dp[0])); for(int i=0;i<50;i++)
    {
        dp[i][0]=0;
    } int max=0; for(int i=1;i<=n;i++)
    { for(int j=1;j<=m;j++)
        { if(a[i-1]==b[j-1])
            {
                dp[i][j] = dp[i-1][j-1]+1; if(dp[i][j]>max)
                    max = dp[i][j];
            } else  {
                dp[i][j] = 0;
            }
        }
    } return max;
} int main()
{ string a,b; while(getline(cin,a))
    {
        getline(cin,b);
        cout<<LCS2(a,b,a.length(),b.length())<<endl;
    } return 0;
}


发表于 2018-04-09 21:46:24 回复(0)
#include <iostream>
#include <cmath>
#include <string>
using namespace std;

int findmax(string a,string b,int m,int n){
    int k=0,l=0;
    for(int i=0;i<a.length()-m && i<b.length()-n;i++){
            if(a[m+i]==b[n+i])  k++;
            else{
                if(k>l) l=k;
                k=0;
                return l;
            }
    }
    return k;
}
int main(int argc, const char * argv[]) {
    string a,b;
    getline(cin,a);
    getline(cin,b);
    int m=0,n=0;
    string temp;
    if(a.length()>b.length()){
        temp = a;
        a = b;
        b = temp;
    }
    for(int i =0;i<a.length();i++){
        for(int j=0;j<b.length();j++){
            if(a[i]==b[j]){
                m = findmax(a, b, i, j);
                if(m>n){
                    n=m;
                }
            }
        }
    }
    cout<<n;
    return 0;
}




发表于 2017-11-07 14:25:39 回复(0)
public static int maxLenghtOfPublicString(String str1, String str2) {
    if (str1.length() == 0 || str2.length() == 0) {
        return 0;
    }
    int maxLength = 0;
    int len1 = str1.length();
    int len2 = str2.length();
    int[] matrix = new int [len1 * len2];
    int i, j;
    // 计算数组
    for (i = 0; i < len1; i++) {
        String s1 = str1.substring(i, i + 1);
        for (j = 0; j < len2; j++) {
            String s2 = str2.substring(j, j + 1);
            int index = i + j * len1;
            int value = s1.equals(s2) ? 1 : 0;
            matrix[index] = value;
        }
    }

    // 统计以i开头的第一个系列的斜线
    String []tmpResult = new String[len1 + len2];
    for (i = 0; i < len1; i++) {

        int tmpI = i;
        StringBuilder sb = new StringBuilder();
        for (j = 0; j < len2 && tmpI < len1; j++, tmpI++) {
            int index = tmpI + j * len1;
            sb.append(matrix[index]);
        }
        int tmpResultIndex = i;
        tmpResult[tmpResultIndex] = sb.toString();
    }

    // 统计以j开头的第一个系列的斜线
    for (j = 0; j < len2; j++) {
        int tmpJ = j;
        StringBuilder sb = new StringBuilder();
        for (i = 0; i < len1 && tmpJ < len2; i++, tmpJ ++) {
            int index = i + tmpJ * len1;
            sb.append(matrix[index]);
        }
        //
        int tmpResultIndex = len1 + j;
        tmpResult[tmpResultIndex] = sb.toString();
    }

    // 求最长连续子序列
    for (i = 0; i < tmpResult.length; i++) {
        int tmpMax = 0;
        String tmpString = tmpResult[i];
        for (j = 0; j < tmpString.length(); j++) {
            int value = Integer.parseInt(tmpString.substring(j, j + 1));
            if (value == 1) {
                tmpMax++;
            } else {
                maxLength = Math.max(maxLength, tmpMax);
                tmpMax = 0;
            }
        }
        maxLength = Math.max(maxLength, tmpMax);
    }


    return maxLength;
}
发表于 2017-11-05 16:49:21 回复(0)