题解 | #查找两个字符串a,b中的最长公共子串#

查找两个字符串a,b中的最长公共子串

https://www.nowcoder.com/practice/181a1a71c7574266ad07f9739f791506

用动态规划寻找最长公共子串的方法,找到最长公共子串,然后找到这个最长公共子串的在较短字符串中的位置

import java.util.Arrays;
import java.util.Scanner;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        while (in.hasNext()) { // 注意 while 处理多个 case
            String a = in.nextLine();
            String b = in.nextLine();
            new Main().maxsharezichuan(a, b);
        }
    }
    void maxsharezichuan(String s1, String s2) {
        int tsr = 0;
        int tsc = 0;
	  //区分出长串和短串,使短串为动态规划表的行,长串为列
        String minstr = "";
        String maxstr = "";
        if (s1.length() < s2.length()) {
            tsr = s1.length() + 1;
            tsc = s2.length() + 1;
            minstr = s1;
            maxstr = s2;
        } else {
            tsr = s2.length() + 1;
            tsc = s1.length() + 1;
            minstr = s2;
            maxstr = s1;
        }
        String out = "";
        int[][] ts = new int[tsr][tsc];
        for (int c = 0; c < tsc; c++) {
            ts[0][c] = 0;
        }
        for (int c = 0; c < tsr; c++) {
            ts[c][0] = 0;
        }
        for (int i = 1; i < tsr; i++) {
            char s1c = minstr.charAt(i - 1);
            for (int j = 1; j < tsc; j++) {
                char s2c = maxstr.charAt(j - 1);
			  //动态规划方法寻找最长公公共子串的公式。
                if (s1c == s2c) {
                    ts[i][j] = 1 + ts[i - 1][j - 1];
                } else {
                    ts[i][j] = 0;
                }
            }
        }
	  //找到表中最大的那个值(这个值在表中不一定是足后一个位置,所以要遍历寻找,也可以在填表时直接找),即为最长公共子串的长度
        int maxrow = 0;
        for (int f = 0; f < tsr; f++) {
            maxrow = Math.max(Arrays.stream(ts[f]).max().getAsInt(), maxrow);
        }
	  //再次遍历,找到这个最大值第一次出现的行,那么行值-1即为最长公共子串结束的位置
        int maxi = 0;
        int maxj = 0;
        for (int i = 0; i < ts.length; i++) {
            for (int j = 0; j < ts[i].length; j++) {
                if (ts[i][j] == maxrow) {
                    maxi = i;
                    maxj = j;
                    break;
                }
            }
            if (maxi > 0 || maxj > 0) {
                break;
            }
        }
	  //根据位置及长度,截取最长公共子串输出
        out = minstr.substring(maxi - maxrow, maxi);
        System.out.println(out);
    }
}

全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务