求两个输入的字符串的最长公共子串

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了求两个输入的字符串的最长公共子串相关的知识,希望对你有一定的参考价值。

如输入 asdfgghj和wwrerasiiy,输出as。如果没有公共子串,则输出“没有公共子串”
c语言编程

    算法:求两个字符串的最长公共子串

    原理:

(1) 将连个字符串分别以行列组成一个矩阵。

(2)。若该矩阵的节点对应的字符相同,则该节点值为1。

(3)当前字符相同节点的值 = 左上角(d[i-1, j-1])的值 +1,这样当前节点的值就是最大公用子串的长。

       (s2)  b  c    d  e

(s1)

a             0  0    0   0

b             1   0   0   0

c             0    2   0  0

d             0    0   3  0

 

3. 结果:只需以行号和最大值为条件即可截取最大子串

 

C# code:

 

[csharp] view plaincopyprint?

public static string MyLCS(string s1, string s2)  

         

           if (String.IsNullOrEmpty(s1) || String.IsNullOrEmpty(s2))  

             

               return null;  

             

           else if (s1 == s2)  

             

               return s1;  

             

           int length = 0;  

           int end = 0;  

           int[,] a = new int[s1.Length, s2.Length];  

           for (int i = 0; i < s1.Length; i++)  

             

               for (int j = 0; j < s2.Length; j++)  

                 

                   int n = (i - 1 >= 0 && j - 1 >= 0) ? a[i - 1, j - 1] : 0;  

                   a[i, j] = s1[i] == s2[j] ? 1+n : 0;  

                   if (a[i, j] > length)  

                     

                       length = a[i,j];  

                       end = i;  

                     

                 

             

           return s1.Substring(end - length + 1, length);  

        

参考技术A 试试看:假设两个字符串最长1000
#include<iostream>
#include<string.h>
using namespace std;

int c[1000][1000];
char str1[1000];
char str2[1000];


void func(int m,int n)
      if((m<0)||(n<0)) return ;

       for(int i=0;i<m;i++)
         for(int j=0;j<n;j++) c[i][j]=0;

      int besti=0,bestj=0;
      int count=0;

      for(int i=0;i<m;i++)
          for(int j=0;j<n;j++)
              if(str1[i]==str2[j]) 
                  if((i==0)||(j==0)) c[i][j]=1;   //增加判断是否为第一个,第一个不能再向下
                  else  c[i][j]=c[i-1][j-1] + 1 ;
              
              else c[i][j]=0;

/*
     for(int i=0;i<m;i++)
         for(int j=0;j<n;j++)
             cout<<c[i][j]<<' ';
         cout<<endl;
     

*/

     for(int i=0;i<m;i++)
         for(int j=0;j<n;j++)
             if(c[i][j]>count)  count=c[i][j]; besti=i; bestj=j;    //查找最长子字符串

     cout<<count<<endl;
     if(count==0) cout<<"没有公共子串"<<endl;  //公共子字符串长度为1,输出“没有公共子串”
     else
        for(int i=besti-count+1;i<=besti;i++) cout<<str1[i];   //否则输出靠X左边(如果多个)子字符串





int main() 
    int m=0;
    int n=0;
    cin>>str1;
    cin>>str2;
    m=strlen(str1);
    n=strlen(str2);
    func(m,n);
    return 0;

追问

看不懂啊,像cout<<endl,这是什么意思。func啥意思。我是c菜鸟,才入门.

追答

c++的标准输出语句,
func是自定义函数
c菜鸟还是先去好好学习基础,这个题目对你来说太难了。

本回答被提问者和网友采纳

求两个字符串的最长公共子串——Java实现

要求:求两个字符串的最长公共子串,如“abcdefg”和“adefgwgeweg”的最长公共子串为“defg”(子串必须是连续的)

public class Main03{
	// 求解两个字符号的最长公共子串
	public static String maxSubstring(String strOne, String strTwo){
		// 参数检查
		if(strOne==null || strTwo == null){
			return null;
		}
		if(strOne.equals("") || strTwo.equals("")){
			return null;
		}
		// 二者中较长的字符串
		String max = "";
		// 二者中较短的字符串
		String min = "";
		if(strOne.length() < strTwo.length()){
			max = strTwo;
			min = strOne;
		} else{
			max = strTwo;
			min = strOne;
		}
		String current = "";
		// 遍历较短的字符串,并依次减少短字符串的字符数量,判断长字符是否包含该子串
		for(int i=0; i<min.length(); i++){
			for(int begin=0, end=min.length()-i; end<=min.length(); begin++, end++){
				current = min.substring(begin, end);
				if(max.contains(current)){
					return current;
				}
			}
		}
		return null;
	}
	
	public static void main(String[] args) {
		String strOne = "abcdefg";
		String strTwo = "adefgwgeweg";
		String result = Main03.maxSubstring(strOne, strTwo);
		System.out.println(result);
	}
}

  

总觉得这题,输出结果和题意不相符合,结果2,是不是把B序列翻转,求出两者最长公共子串

以上是关于求两个输入的字符串的最长公共子串的主要内容,如果未能解决你的问题,请参考以下文章

求最长公共子串

求两个字符串的最长公共子串——Java实现

MATLAB 最长公共子序列

java 两个字符串,求最长公共子串的长度

3160 最长公共子串

codevs 3160 最长公共子串(SAM)