最長公共子串問題(可輸出多個子串)
阿新 • • 發佈:2019-02-13
//最長公共子串,可輸出多個 public class TestLCS { public static void getLCString(char[] str1, char[] str2) { int i, j; int len1, len2; len1 = str1.length; len2 = str2.length; int maxLen = len1 > len2 ? len1 : len2; int[] max = new int[maxLen]; int[] maxIndex = new int[maxLen]; int[] c = new int[maxLen]; // 記錄對角線上的相等值的個數 for (i = 0; i < len2; i++) { for (j = len1 - 1; j >= 0; j--) { if (str2[i] == str1[j]) { if ((i == 0) || (j == 0)) c[j] = 1; else c[j] = c[j - 1] + 1; } else { c[j] = 0; } if (c[j] > max[0]) { // 如果是大於那暫時只有一個是最長的,而且要把後面的清0; max[0] = c[j]; // 記錄對角線元素的最大值,之後在遍歷時用作提取子串的長度 maxIndex[0] = j; // 記錄對角線元素最大值的位置 //每一組max[k]和maxindex[k]對應記錄了一組最長子串,如果發現c[j]>max[0],則之前記錄的當前找到的最長子串都失效,所以要清空 for (int k = 1; k < maxLen; k++) { max[k] = 0; maxIndex[k] = 0; } } else if (c[j] == max[0]) { // 有多個是相同長度的子串 //每一組max[k]和maxindex[k]對應記錄了一組最長子串 for (int k = 1; k < maxLen; k++) { if (max[k] == 0) { max[k] = c[j]; maxIndex[k] = j; break; // 在後面加一個就要退出迴圈了 } } } } } for (j = 0; j < maxLen; j++) { if (max[j] > 0) { System.out.println("第" + (j + 1) + "個公共子串:"); for (i = maxIndex[j] - max[j] + 1; i <= maxIndex[j]; i++) System.out.print(str1[i]); System.out.println(" "); } } } public static void main(String[] args) { String str1 = new String("abcd"); String str2 = new String("dcba"); getLCString(str1.toCharArray(), str2.toCharArray()); } }