查找最长公共子串

博客围绕最长公共子串展开,指出动态规划经典问题是最长公共子序列,而公共子串要求序列连续。介绍了依次比较的简单方法,重点说明用递归查找最长公共子串,还提到为方便调试直接赋值字符串,去掉注释符可换其他字符串。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

用递归查找最长公共子串

动态规划有一个经典问题是最长公共子序列,但是这里的子序列不要求连续,如果要求序列是连续的,我们叫公共子串,那应该如何得到这个串呢?

最简单的方法就是依次比较,以某个串为母串,然后生成另一个串的所有长度的子串,依次去母串中比较查找,这里我们用递归查找最长公共子串。

import java.util.Scanner;
public class lookup {
 public static int  lcs(char[] x,char[] y,int i,int j) {
  if(i==0||j==0)
  return 0;
  else if(x[i]==y[j]) {
   return lcs(x,y,i-1,j-1)+1;
  }
  else
   return Math.max(lcs(x,y,i-1,j), lcs(x,y,i,j-1));
  
 }
  public static void main(String[] args) {
  String x="ABCBDAB";
  String y="BDCABA";
//  Scanner in=new Scanner(System.in);
//  System.out.println("请输入父集合");
//  x=in.nextLine();
//  System.out.println("请输入子集合");
//  y=in.nextLine();
  char [] c1=new char[x.length()+1];
  char [] c2=new char[y.length()+1];
  char[] t1=x.toCharArray();
  char [] t2=y.toCharArray();
  c1[0]=(char)0;
  c2[0]=(char)0;
  for(int i=0;i<t1.length;i++) {
   c1[i+1]=t1[i];
  }
  for(int i=0;i<t2.length;i++) {
   c2[i+1]=t2[i];
  }
  System.out.println(lcs(c1,c2, c1.length-1, c2.length-1));
 }
}

这里我为了方便调试,我直接将两个字符串赋值,如果想要其他的字符串直接将注释符去掉即可。

这是运行结果

### C语言实现最长公共子串算法 以下是基于动态规划方法的C语言实现,用于查找两个字符串之间的最长公共子串。此代码逻辑与引用中的描述一致[^1]。 ```c #include <stdio.h> #include <string.h> #define MAX_LEN 1000 char str1[MAX_LEN]; char str2[MAX_LEN]; // 动态规划表 int dp[MAX_LEN][MAX_LEN]; int main() { printf("请输入第一个字符串:\n"); scanf("%s", str1); printf("请输入第二个字符串:\n"); scanf("%s", str2); int len1 = strlen(str1); int len2 = strlen(str2); int maxLength = 0; // 记录最长公共子串的长度 int endIndex = 0; // 记录最长公共子串在str1中的结束位置 for (int i = 1; i <= len1; i++) { for (int j = 1; j <= len2; j++) { if (str1[i - 1] == str2[j - 1]) { // 如果字符匹配 dp[i][j] = dp[i - 1][j - 1] + 1; if (dp[i][j] > maxLength) { maxLength = dp[i][j]; // 更新最大长度 endIndex = i - 1; // 更新结束索引 } } else { dp[i][j] = 0; // 字符不匹配,则重置为0 } } } // 输出最长公共子串及其长度 if (maxLength > 0) { char longestCommonSubstring[maxLength + 1]; strncpy(longestCommonSubstring, str1 + endIndex - maxLength + 1, maxLength); longestCommonSubstring[maxLength] = '\0'; printf("最长公共子串: %s\n", longestCommonSubstring); printf("其长度为: %d\n", maxLength); } else { printf("无公共子串。\n"); } return 0; } ``` #### 解析 上述程序实现了最长公共子串的功能。它利用了动态规划的核心思想,定义了一个二维数组`dp`来保存中间状态的结果。具体来说: - `dp[i][j]`表示以`str1[i-1]`和`str2[j-1]`结尾的最长公共子串的长度。 - 当`str1[i-1]==str2[j-1]`时,有关系式`dp[i][j] = dp[i-1][j-1] + 1`成立[^2]。 - 同时,在每次更新`dp[i][j]`的过程中,会同步维护变量`maxLength`以及对应的结束索引`endIndex`以便最终提取出完整的最长公共子串[^3]。 时间复杂度方面,由于需要遍历整个二维表格,因此总体的时间复杂度为\(O(n \times m)\),其中\(n\)和\(m\)分别为输入字符串的长度。而空间复杂度同样为\(O(n \times m)\)[^4]。 --- ###
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值