動態規划解決最長公共子序列問題


最長公共子序列問題又稱LCS問題(longest common subsequence problem)

 問題描述:

給你兩個字符串str1和str2,它們之間可能存在公有子序列,子序列和子串的區別是:子序列不要求連續,只需要按照順序出現就好,子串則要求連續:

例如:SIMPLE和NAIVE有共同的子序列IE,但是沒有共同的子串。

      TOO SIMPLE和TOO YOUNG則有共同子串TOO

 

LCS問題就是(1)求出最長公有子序列的長度(2)求出最長公有子序列。

 

(1) 求出最長公有子序列的長度

解法考慮動態規划,用一個二維數組L [m][n]存狀態, L [i][j]的含義是str1前i項和str2的前j項最長的公共子序列的長度。

寫出狀態轉移方程:

第二個式子比較好理解,

第三個我是這么理解的,本應該是求:

可是很顯然第三項是最小的,所以省略了。

 

(2)輸出一個LCS

從狀態表右下角開始往前回溯,當前字符相等,則存入結果字符串,當前字符不相等,比較狀態表上方與左方的值,並移動到最大值位置,重復上述步驟,直到到達邊界。反序輸出結果字符串。

 

上代碼:

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<string.h>
 4 int LCS(char*a,char*b){
 5     int m=strlen(a);
 6     int n=strlen(b);
 7     int L[m][n];
 8     int i,j;
 9     char res[20];
10     int k=0;
11         
12     for(i=0;i<m;i++){
13         for(j=0;j<n;j++){
14             if(i==0||j==0){
15                 L[i][j]=0;      //case 1     
16             }else{
17                 if(a[i]==b[j]){
18                     L[i][j]=L[i-1][j-1]+1;  //case 2
19                 }else{
20                     L[i][j]=L[i-1][j]>L[i][j-1]?L[i-1][j]:L[i][j-1]; // case 3
21                 }    
22             }
23             printf("%d ",L[i][j]);    
24         }
25         printf("\n");
26     }
27     
28     for(i=m-1,j=n-1;i>=0&&j>=0;){
29         if(a[i]==b[j]){
30             res[k++]=a[i];
31             i--;
32             j--;
33             
34         }else{
35             if(L[i-1][j]>L[i][j-1]){
36                 i--;
37             }else{
38                 j--;
39             }    
40         }
41     }
42 
43     printf("\nLCS:");
44     for(i=strlen(res)-1;i>=0;i--){
45         printf("%c",res[i]);
46     }
47     printf("\n");
48         
49     return L[m-1][n-1];    
50 }
51 int main(){
52     char str1[50];
53     char str2[50];
54     strcpy(str1,"SIMPLE");
55     strcpy(str2,"NAIVE");
56     int ret;
57     
58     ret=LCS(str1,str2);
59     printf("length of LCS:%d\n",ret);
60     return 0;
61 }

 


免責聲明!

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



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