2021-04-08

求两个字符串的最大公共子串

思路一 暴力求解

没有实际写代码验证,只写一下我的思路。

  1. 比较得到较短的字符串str1
  2. 计算较短字符串的所有公共子串,存放在集合中
    2.1 找子串的思路:两个循环,外层从0遍历到末尾,内层从当前的位置开始,逐个字符增加
  3. 对集合中所有的子串按长度排序(需要自定义比较器,可能比较复杂)
  4. 从大的子串到小的子串循环,一次进行str2.contains(子串i)
思路二 动态规划
  1. 构造一个大小为字符串长度的二维数组
  2. 二维数组的a[i][j]值为0或者1,如果是0,表示str1[i] != str2[j] ,反之则是1

比如:abcde和ggbddgg的矩阵如下

0 0 0 0 0 0 0 
0 0 1 0 0 0 0 
0 0 0 1 0 0 0 
0 0 0 0 1 0 0 
0 0 0 0 0 0 0

3.对角线最长的1序列就是我们要求的最大长度为3
这种方式的难点在于如何求出对角线最长的1序列

思路二 改进

步骤2,我们可以计算出如果str1[i] == str2[j]时,a[i][j] = a[i][j] + a[i-1][j-1]
得到的二维数组如下

0 0 0 0 0 0 0 
0 0 1 0 0 0 0 
0 0 0 2 0 0 0 
0 0 0 0 3 0 0 
0 0 0 0 0 0 0

矩阵中最大的值就是最大公共子串

代码实现(java)
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while(scanner.hasNextLine()) {
            char[] line1 = scanner.nextLine().toCharArray();
            char[] line2 = scanner.nextLine().toCharArray();
            int max = Integer.MIN_VALUE;
            int[][] a = new int[line1.length][line2.length];
            for (int i = 0; i < line1.length; i++) {
                for (int j = 0; j < line2.length; j++) {
                    // 所有的值,得出是0还是1(是否相等)
                    a[i][j] = line1[i] == line2[j] ? 1 : 0;
                    // 非0行0列时,且相等时,加左上角的值
                    if (i != 0 && j != 0 && a[i][j] == 1) {
                        a[i][j] += a[i - 1][j - 1];
                    }
                    //System.out.print(a[i][j] + " ");
                    // 判断a[i][j]和现有最大长度,更新max
                    if (max < a[i][j]) {
                        max = a[i][j];
                    }
                }
                // System.out.println();
            }
            System.out.println(max);
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值