最長公共子字串
阿新 • • 發佈:2019-01-10
題目原意為:給出兩個字串,求出這樣的一 個最長的公共子序列的長度:子序列 中的每個字元都能在兩個原串中找到, 而且每個字元的先後順序和原串中的 先後順序一致。
遞推原則:對於S1字串第i個位置之前的子字串,和S2字串第j個位置之前的子字串,這兩者之間公共子字串的長度取決於第i-1個位置和第j-1個位置上的字元是否相等,若相等,則長度可更新為Max_len(i-1,j-1)+1; 如果這兩個位置上的字元不相等,則將i向前推一位,即Max_len(i-1,j),或將j往前推一位,即Max_len(i,j-1),比較這兩個Max_len之間的大小關係,來得到Max_len的值。注意:這裡通過這樣的比較方式得出Max_len(i,j)的值,在其後面不需要+1,因為是根據之前已經確定的子字串長度來推出目標位置的子字串,目標位置並沒有新的公共字元增加,因此不需要在後面+1!
為了節約空間和運算時間,定義一個數組用以儲存每一對index位置上對應的公共字元的個數,這樣當下一對index需要訪問時就可以隨時取用而不用重複計算
程式碼實現如下:
package Dynamic_P; import java.util.Scanner; public class Max_subLine { public static void main(String args[]) { Scanner scan=new Scanner(System.in); char []ch1=scan.nextLine().toCharArray(); char []ch2=scan.nextLine().toCharArray(); int len1=ch1.length; int len2=ch2.length; int [][]Max_len=new int[len1+1][len2+1]; //當S1為0或S2為0時,這兩個字串之間的公共長度為0 for(int i=0;i<=len1;i++) Max_len[i][0]=0; for(int i=0;i<=len2;i++) Max_len[0][i]=0; //在這個迴圈遍歷的部分,相當於每一次固定S1字串中的某一個長度,再依次增長S2固定的長度, //由於這兩個長度之間的公共字元的個數都是由之前更短的S1字串或者S2字串得來的,就會直接更新相應的Max_len陣列中的值 for(int i=1;i<=len1;i++) { for(int j=1;j<=len2;j++) { if(ch1[i-1]==ch2[j-1]) Max_len[i][j]=Max_len[i-1][j-1]+1; else Max_len[i][j]=Math.max(Max_len[i-1][j], Max_len[i][j-1]); } } System.out.println(Max_len[len1][len2]); } }