若給定序列x=,則另一串行z=,是x的子串行是指存在乙個嚴格遞增下標序列使得對於所有j=1,2,…,k有:zj=xij。例如,序列z=是序列x=的子串行,相應的遞增下標序列為。
給定2個序列x和y,當另一串行z既是x的子串行又是y的子串行時,稱z是序列x和y的公共子串行。
給定2個序列x=和y=,找出x和y的最長公共子串行。
需要遍歷出所有的可能,時間複雜度是o(n³),太慢了
分析規律:
設x=,y=為兩個序列,z=是他們的任意公共子串行
經過分析,我們可以知道:
1、如果xm = yn,則zk = xm = yn 且 zk-1是xm-1和yn-1的乙個lcs
2、如果xm != yn 且 zk != xm,則z是xm-1和y的乙個lcs
3、如果xm != yn 且 zk != yn,則z是x和yn-1的乙個lcs
所以如果用乙個二維陣列c表示字串x和y中對應的前i,前j個字元的lcs的長度話,可以得到以下遞迴公式:
因此,我們動態規劃就可以以自底向上的方式進行求解
只需要從c[0][0]開始填表,填到c[m-1][n-1],所得到的c[m-1][n-1]就是lcs的長度
int lcslength(int m,int n,char *x,char *y,int **c,int **b) //c陣列用來記錄子串行長度,b陣列記錄具體的子串行,構造序列時 可以用到!
for(int j=0;j<=n;j++)
for(int i=1;i<=m;i++) //填表
for(int j=1;j<=n;j++)else if(c[i-1][j]>=c[i][j-1])}}
但是,我們怎麼得到lcs本身而非lcs的長度呢?
上面的b陣列就派上了用場!b[i][j]記錄的是c[i][j]的值是由哪個子問題的解得到的,因此,從b[m][n]反向遍歷陣列即可得到具體的最長公共子串行!
動態規劃 最長公共子串行
問題描述 我們稱序列z z1,z2,zk 是序列x x1,x2,xm 的子串行當且僅當存在嚴格上公升的序列 i1,i2,ik 使得對j 1,2,k,有xij zj。比如z a,b,f,c 是x a,b,c,f,b,c 的子串行。現在給出兩個序列x和y,你的任務是找到x和y的最大公共子串行,也就是說要...
動態規劃 最長公共子串行
兩個序列的最長公共子序 lcs longest common length 的 每個字元可以不連續,如x y 那麼它們的最長公共子串行為。這是乙個經典的動態規劃問題,著手點還是找到 最精髓的 狀態轉移方程 假設x,y兩個序列的前i,j個位置的最大子串行已經找到為r i j 自底往上 那麼x i 與y...
動態規劃 最長公共子串行
看完演算法導論關於這部分內容之後的總結 關於最長公共子串行問題 給定兩個子串行 x y 求x和y長度最長的公共子串行。解決方法 首先先要了解lcs的最優子結構,令x y 為兩個子串行,z 為x和y的任意lcs。1 如果 xm yn 則 zk xm yn 且 zk 1 是 xm 1 和 yn 1 的乙...