题解 | #查找两个字符串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); } }