1、問題相關定義:
(1)字串:乙個字串s是將n 個字元順次排列形成的陣列, n稱為s的長度,表示為len(s) 。s的第i字元表示為s[ i ]。
(2)子串:字串s的子串s[ i:j ] ( i ≤ j)表示s串中從i到j這一段,也就是排列s[ i ] , s[ i + 1 ] , ⋯,s[ j ] 形成的字串。
(3)字尾:字尾是指從某個位置i開始到整個串末尾結束的乙個特殊子串。字串s的從i開頭的字尾表示為suffix( s,i) ,也就是suffix( s, i) = s[ i:len ( s) ]。
(4)公共字尾:字串u 如果既是字串s的字尾又是字串t的字尾,則字串u 是字串s和t的乙個公共字尾。
(5)最長公共字尾:字串s和t的最長公共字尾是指字串s和t的所有公共字尾中長度最大的子串。
(4)公共子串:字串u 如果既是字串s的子串又是字串t的子串,則字串u 是字串s和t的乙個公共子串。
(5)最長公共子串:字串s和t的最長公共子串是指字串s和t的所有公共子串中長度最大的子串。
例:給定2 個長度分別為4, 4 的字串「abab」,「baba」,它們的公共子串(common substring) 有「」,「a」,「b」,「ab」,「ba」,「aba」,「bab」。其中最長公共子串(lcs) 即為「aba」或「bab」。
2、動態規劃求解
在使用動態規劃求解2個長度分別為p, q的字串s,t的最長公共子串問題前,先給出求它們任意字首子串對s[1:i],t[1:j]的最長公共字尾的演算法,其中:1 ≤ i ≤ p,1 ≤ j ≤ q。設lcsuffix(s[1:i],t[1:j])表示字首子串對s[1: i] ,t[1:j] 的最長公共字尾,則該問題的遞推關係式如下:
例如:字串s「baba」, t「abab」, 使用上面遞推關係式求得字串s, t所有字首子串對的最長公共字尾,如下表所示:
字串s, t所有字首子串對應的最長公共字尾中長度最大的即為字串s, t的最長公共子串,即:
[cpp]view plain
copy
// cpppro.cpp : 定義控制台應用程式的入口點。
//3m6 最長公共子串,動態規劃實現
#include "stdafx.h"
#include
#include
using
namespace
std;
string getlcslength(string &s, string &t);
intmain()
string getlcslength(string &s, string &t)
char
char1 =
'\0'
; char
char2 =
'\0'
; int
len = 0;
string lcs = ""
; for
(int
i=0; i
else
else
if(num[i][j].length()>len)
else
if(num[i][j].length()==len)
} } }
for(
inti=0;i
delete
num;
return
lcs;
}
程式執行結果如下:
使用動態規劃演算法求2個長度分別為p, q的字串s, t的最長公共子串需要構造乙個二維表,該二維表含有pq個項,使用遞推的方法求每項的時間負責度為o (1) ,所以求出所有項的時間複雜度為o (pq) 。在二維表中只需找到乙個最大值項,其對應於原2個字串的最長公共子串,因此使用動態規劃演算法的時間複雜度為o (pq) 。
建立2個長度分別為p, q的字串s, t的廣義字尾陣列的時間複雜度為o (p + q) ,求廣義字尾陣列中相鄰子串的最長公共字首的時間複雜度為,即需要預處理時間複雜度為o(p + q) ,每次查詢最長公共字首的時間複雜度為o(1) 。遍歷所有最長公共字首的時間複雜度為o(p+q) ,因此使用廣義字尾陣列解決最長公共子串的時間複雜度為o(p+q) 。對於字串s, t,它的廣義字尾陣列在不降低效能同時需要使用2 (p + q) 空間。
解決2個長度分別為p, q的字串最長公共子串問題的動態規劃演算法,廣義字尾樹演算法以及廣義字尾陣列演算法在時間複雜度,空間複雜度以及程式設計實現上的比較分析總結如下表所示:
其中動態規劃演算法以及廣義字尾樹演算法的研究已經非常成熟,在計算機演算法領域有著各種各樣的應用,但在解決字串最長公共子串問題上還有一定不足,即動態規劃演算法占用的時間複雜度以及空間複雜度都很高,而廣義字尾樹演算法雖然降低了時間複雜度,但其空間複雜度還是較高,另外程式設計實現也較難。雖然廣義字尾陣列的理論研究還在發展中,但就目前的研究成果而言,在解決字串最長公共子串問題上,根據上面給出的演算法,它可以綜合動態規劃演算法以及廣義字尾樹演算法的優點,既保證了線性的時間複雜度,較低的空間複雜度又易於程式設計實現。改進的字尾陣列演算法及相關定義應用可檢視博文《最長公共子串問題的字尾陣列解法》。
動態規劃之最長公共子串行演算法
動態規劃之最長公共子串行演算法 演算法思想 假設x x1,x2,xm y static void init xy void getchar for i 1 i n i getchar static void lcs length void else if c i 1 j c i j 1 else p...
演算法 最長公共子串行(動態規劃)
給定兩個字串 text1 和 text2,返回這兩個字串的最長公共子串行的長度。乙個字串的 子串行 是指這樣乙個新的字串 它是由原字串在不改變字元的相對順序的情況下刪除某些字元 也可以不刪除任何字元 後組成的新字串。例如,ace 是 abcde 的子串行,但 aec 不是 abcde 的子串行。兩個...
演算法題9 動態規劃之最長公共子串行 最長公共子串
題目 如果字串1的所有字元按其在字串中的順序出現在另外乙個字串2中,則字串1稱之為字串2的子串行。注意,並不要求子子串行 字串1 的字元必須連續出現在字串2中。請編寫乙個函式,輸入兩個字串,求它們的最長公共子串,並列印出最長公共子串行。例如 輸入兩個字串bdcaba和abcbdab,字串bcba和b...