Java 最長子序列和最長子串[算法練習]


  • 最長子序列:匹配的字符不需要連續。
  • 最長子串: 匹配的字符需要連續,可能有多種結果。

解決思路:將輸入字符串1看作行, 輸入字符串2看作列,構成二位數組,然后將對角線匹配字符的值標記為1,計算滿足條件的匹配字符個數即可。

基本思想: 空間換時間,動態規划。

 

 

圖解與公式(只針對最長子序列,最長子串類似)

狀態轉移方程

 

 

直觀版:

最長子序列

 1     /**
 2      * find longest common sequence from two input string
 3      * @param s1
 4      * @param s2
 5      * @return length of longest common sequence
 6      */
 7     public static int LCS(String s1, String s2) {
 8         int[][] c = new int[s1.length()][s2.length()];
 9 
10         // initialize the elements without top left element
11         for(int i=0; i<s1.length();i++){
12             if (s1.charAt(i) == s2.charAt(0)) {
13                 c[i][0] = 1;
14             }
15         }
16         for(int j = 0; j<s2.length();j++){
17             if (s1.charAt(0) == s2.charAt(j)) {
18                 c[0][j] = 1;
19             }
20         }
21         for (int i = 1; i < s1.length(); i++) {
22             for (int j = 1; j < s2.length(); j++) {
23                 if (s1.charAt(i) == s2.charAt(j)) {
24                     c[i][j] = c[i - 1][j - 1] + 1;
25                 } else if (c[i][j - 1] > c[i - 1][j]) {
26                     c[i][j] = c[i][j - 1];
27                 } else {
28                     c[i][j] = c[i - 1][j];
29                 }
30             }
31         }
32         return c[s1.length() - 1][s2.length() - 1];
33     }

最長子序列也可以用穩定的排序算法先排序,再匹配。如采用歸並排序算法(注意,快速排序不穩定)。 

 

最長子串

 1     /**
 2      * find longest substring from two input string
 3      *
 4      * @param s1
 5      * @param s2
 6      * @return length of longest substring
 7      */
 8     public static int LSS(String s1, String s2) {
 9         int[][] c = new int[s1.length()][s2.length()];
10         int max = 0;
11 
12         // initialize the elements without top left element
13         for(int i=0; i<s1.length();i++){
14             if (s1.charAt(i) == s2.charAt(0)) {
15                 c[i][0] = 1;
16             }
17         }
18         for(int j = 0; j<s2.length();j++){
19             if (s1.charAt(0) == s2.charAt(j)) {
20                 c[0][j] = 1;
21             }
22         }
23 
24         for (int i = 1; i < s1.length(); i++) {
25             for (int j = 1; j < s2.length(); j++) {
26                 if (s1.charAt(i) == s2.charAt(j)) {
27                     c[i][j] = c[i - 1][j - 1] + 1;
28                     if (c[i][j] > max) {
29                         max = c[i][j];
30                     }
31                 }
32             }
33         }
34         return max;
35     }

 

 優化版:

待續..

優化基本思想:

可以采用遞歸方式,盡早舍棄不符合要求的匹配。

對於優化最長子串,

  可以優先查找最長子串,如果發現一個匹配,就一直找下去,同時將最終的不匹配標記為-1而不是0.

  如果剩余的可能匹配長度小於已找到的長度,則停止遞歸操作,直接return.

 

其他相關算法

Horspool's Algorithm and Boyer-Moore Algorithm


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM