java 走進NLP 最長公共子串LSC演算法

2021-09-13 22:52:14 字數 1927 閱讀 8865

最長公共子串(lcs),有三種情況: 1.公共子串的元素必須相鄰 2.公共子串的元素可以不相鄰 3.求多個字串而不是兩個字串的最長公共子串。

情況1:公共子串的元素必須相鄰

解決方法是採用乙個矩陣來記錄兩個字串中所有位置的兩個字元之間的匹配情況,若是匹配則為1,否則為0。然後求出對角線最長的1序列,其對應的位置就是最長匹配子串的位置。例如:a串作為x軸,b串作為y軸,矩陣對應位置表示兩個字元之間的匹配情況,從矩陣可以找到,黃色部分是最長的匹配子串。如圖1所示:

但是在0和1矩陣中找最長的1對角線序列又要花去一定的時間。通過改進矩陣的生成方式和設定標記變數,可以省去這部分時間。如圖2所示:

演算法的基本思想:當字元匹配的時候,並不是簡單的給相應元素賦上1,而是賦上其左上角元素的值加1。這樣用兩個標記變數來標記矩陣中值最大的元素的位置,在矩陣生成的過程中來判斷當前生成的元素的值是不是最大的,據此來改變標記變數的值,那麼到矩陣完成的時候,最長匹配子串的位置和長度就已經出來了。**如下:

public class longestsubstring 

int matrix = new int[n][m];

for(int i = 0; i < n; i++)

}int max = 0;

for(int i = 0; i < n; i++)else

max = (max > matrix[i][j] ? max : matrix[i][j]);}}

}return max;

}public static void main(string args)

}

執行結果:

4

0.4444444444444444

process finished with exit code 0

情況2:公共子串的元素可以不相鄰

例如,輸入: 「1a2c3d4b56」,10,「b1d23ca45b6a」,12,返回: 6

採用動態規劃演算法,dp陣列中的i和j分別表示在兩串中,分別取到前i位和前j位時,兩個字首子串所遞推得到的最長公共子串行。 將陣列中的dp[i][0]和dp[0][i]分別初始化為0,表示無論i是多少,另乙個串字首取i位,與當前串的空串都不會有任何公共子串行。 然後開始遞推,遍歷i,j以對比兩串中相等的字元,一旦遇到相等的字元,將從i-1,j-1的位置繼承狀態,並延續繼承到的最長公共子串行的記錄值,也就是+1操作,表示當兩串的第i位字元和第j位字元相等時,將從不包括這兩個字元的字首子串裡得到的最長公共子串行+1,得到當前位置的新的最長公共子串行。也就是求解當前i,j的狀態,來自於i-1,j-1的狀態+1獲得。而當i,j位置的字元不等時,當前位不能延續最長公共子串行的值,只能從之前i-1,j 和i,j-1取最大值繼承。這樣遞推,將得到整個串的最長公共子串行。狀態轉移方程:

// 每個字元進行比較

for(int i=0;idp[i][j+1] ? dp[i+1][j] : dp[i][j+1];}}

}return dp[n][m];

}public static void main(string args)

}執行結果:

6

0.5process finished with exit code 0

最長公共子子串 java

package maxcommon 找到最長公共子串,可以不連續 agta和aggct最長公共子串為agt author root public class maxcommonunseries 普通遞迴方法 public static string find char s1,int s1 b,cha...

最長公共子串行 最長公共子串

1 最長公共子串行 採用動態規劃的思想,用乙個陣列dp i j 記錄a字串中i 1位置到b字串中j 1位置的最長公共子串行,若a i 1 b j 1 那麼dp i j dp i 1 j 1 1,若不相同,那麼dp i j 就是dp i 1 j 和dp i j 1 中的較大者。class lcs el...

最長公共子串行 最長公共子串

1.區別 找兩個字串的最長公共子串,這個子串要求在原字串中是連續的。而最長公共子串行則並不要求連續。2 最長公共子串 其實這是乙個序貫決策問題,可以用動態規劃來求解。我們採用乙個二維矩陣來記錄中間的結果。這個二維矩陣怎麼構造呢?直接舉個例子吧 bab 和 caba 當然我們現在一眼就可以看出來最長公...