動態規劃之最長公共子序列(C++原始碼)
阿新 • • 發佈:2018-12-19
動態規劃之最長公共子序列
問題:
在序列X={x1,x2,…,xm}與Y={y1,y2,…,yn}中查詢長度最長的公共子序列,往往不是一個。例如:X={A,B,C,B,D,A,B},Y={B,D,C,A,B,A},則公共子序列有Z={B,C,B,A},Z1={B,D,A,B},Z2={B,C,A,B}
分析:
用c[i][j]記錄序列Xi和Yi的最長公共子序列的長度。當i=0或者j=0時,Xi和Yi的最長公共子序列為空,所以c[i][j]=0。 其他情況:當xi=yi時,c[i][j]=c[i-1][j-1]+1。當xi不等於yi時,c[i][j]=max{c[i][j-1],c[i-1][j]}
程式碼:
#include<bits/stdc++.h> using namespace std; #define num 100 int c[num][num];//存放i,j之間最大公共子序列的長度 int b[num][num];//記錄c[i][j]的值是哪得來的 void LCS(int m,int n,const char x[],const char y[]){ int i,j; for(i=1;i<=m;i++){ c[i][0]=0; } for(i=1;i<n;i++){ c[0][i]=0; } for(i=1;i<=m;i++){ for(j=1;j<=n;j++){ if(x[i]==y[i]){ c[i][j]=c[i-1][j-1]+1; b[i][j]=1; } else{ if(c[i-1][j]>=c[i][j-1]){ c[i][j]=c[i-1][j]; b[i][j]=2 } } else{ c[i][j]=c[i][j-1]; b[i][j]=3; } } } }
由演算法得到的陣列b可用於快速構造序列X和Y的最長公共子序列
void LCS(int i,int j,char x[]){
if(i==1||j==0){return;}
if(b[i][j]==1){
LCS(i-1,j-1,x)
}
else{
if(b[i][j]=2){
LCS(i-1,j,x);
}
}
else{
LCS(i,j-1,x);
}
}
主函式:
int main(){ char x[num]; char y[num]; int m,n; cin>>m; for(int i=1;i<=m;i++){ cin>>x[i]; } cin>>n; for(int i=1;i<=n;i++){ cin>>y[i]; } cout<<"----------------"<<endl; LCSLength(m,n,x,y); cout<<c[m][n]<<endl; LCS(m,n,x); return 0; }