給出兩個字串,求出這樣的一
個最長的公共子串行的長度:子串行
中的每個字元都能在兩個原串中找到,
而且每個字元的先後順序和原串中的
先後順序一致。
sample input:
abcfbc abfcab
programming contest
abcd mnp
sample output:
4 2
0對於動態規劃的問題,最重要的一步就是找出狀態轉移方程。那麼最長公共子串行的狀態方程是什麼呢?我們來分析分析。
假設有兩個字串a和b:a串為a1 a2 a3 … am; b串為b1 b2 b3 …bn。
ax為從a1開始到ax的連續字串,by為從b1開始到by的連續字串
假設l[x][y]為ax和by的最長公共子串的長度。
那麼,我們很容易得出:
如果ax==by,則l[x][y] = l[x-1][y-1] + 1。
如果ax和by不相等呢?那麼l[x][y]就等於l[x][y-1]和l[x-1][y]中更大的那乙個。具體是哪個呢?我們不必知道。因為已經有了當前狀態與之前狀態的關係,我們只需要給出最初狀態,計算機就可以幫我們一步一步計算出結果。
容易想到:當x==0 || y==0 時,l[x][y] = 0 即當字串a的長度為0或者字串b的長度為0時,最長公共子串行的長度必然為0(空字串)。
據此,就可以寫出最長公共子串行的狀態轉移方程:
有了狀態轉移方程,求出最長公共子串行的長度輕而易舉。
那麼我們怎麼求出最長公共子串行本身呢?答案其實也在狀態轉移方程中:我們把l想象成乙個二維陣列,當ax等於by時,l[x][y]只有一條路可以走:l[x-1][y-1] + 1。
所以只要當l[x][y]的值比l[x-1][y-1]大,我們就可以知道此時ax等於by。既然ax等於by了,那此時的ax和by一定是字串a和字串b的公共元素,也是最長子序列的公共元素。自然,最長子序列中包含它們了。如果不是走上面的路,那麼l[x][y] 的值就是l[x-1][y] 與l[x][y-1]中較大的那個,此時ax不等於by。所以我們只需要比較l[x-1][y] 與l[x][y-1],較大的就是l[x][y]來時的路。就這樣,根據狀態轉移方程和計算出的二維陣列l,就可以倒推出最長公共子串行的所有元素的逆序。
值得注意的一點就是:當l[x][y] = max(l[x-1][y], l[x][y-1]) 時,我們只用了l[x-1][y] 與 l[x][y-1] 中較大的那個。如果它倆相等呢?如果相等的話,我們推出來的二維陣列l的結果不會變化;但是我們倒推出的最長公共子串行就不一樣了:
我們在選擇l[x][y] = l[x-1][y]或者選擇l[x][y] = l[x][y-1],對於乙個二維陣列l而言,肯定是兩條不一樣的路徑。所以最長公共子串行的序列不一定只有乙個,或者是乙個,或者是2個,或者是4個…
**如下:
#include
#include
#include
#define max 10000
struct data;
typedef
struct datas datas;
int l[max][max];
int my_max(int a, int b)
int lcs(char a, char b, int m, int n)
else}}
for(i = 0; i<=m; i++)
printf("\n");
}printf("\n");
return l[m][n];
}int main()
}else
}else
fclose(fp);
}else
for(i = 0; ii; i++)
else
if (l[m][n] == l[m-1][n])
else n--;
}printf("\n\n\n");
}free(datas);
return
0;}
ps: 最近複習了檔案讀取和柔性陣列,為了鞏固知識,就在解最長公共子串行的時候加上了它們。**中用的檔案「data.txt」 ,放在該c檔案的相同目錄下。以下是data.txt中的內容
4
abcfbc
abfcab
13456778
357486782
abcd
mnp97862641
8761
動態規劃之最長公共子串行
最長公共子串行簡介 舉例說明並分析 塊測試結果 乙個給定序列的子串行是在該序列中刪去若干元素後得到的序列,確切的說,若給定序列x 則另一串行z x的子串行是指存在乙個嚴格的下標序列,使得對於所有的j 0,1,k 1有zj xij。例如序列z 是序列x 的子串行,相應的遞增下標序列維。最長公共子串行問...
動態規劃之最長公共子串行
最長公共子串行問題 time limit 1000 ms memory limit 65536 kib submit statistic discuss problem description 給定兩個序列x input 輸入資料有多組,每組有兩行 每行為乙個長度不超過500的字串 輸入全是大寫英文...
動態規劃之最長公共子串行
給定兩個序列x和y,稱z是x和y的公共子串行,如果z既是x的子串行,又是y的子串行 最長的公共子串行稱作最長公共子串行lcs longest common subsequence 1 lcs的最優子結構 設zk是xm和yn的乙個lcs,則,如果x和y的最後乙個元素相同,則z中去掉最後乙個元素之後zk...