鄧俊輝版資料結構,動態規劃求解最長公共子串行學習總結。
第一種方法是通過遞迴實現。思路如下,兩字串長度長度分別為 a,b,比較他們的末位字元,這裡是有三種情況
若有一方長度為零,則返回「」,這是遞迴方程的遞迴基。
若兩字串的末位字元相同,去掉末尾字元,返回規模遞減的問題f(a-1,b-1)。這裡是「減而治之」策略。
若兩字串末位字元不同,則有兩種情況通過比較(a-1,b) 和(a,b-1)長度的字串的最長公共子串行的長度,像長度較大的方向繼續進行遞迴,返回f(a-1,b)或f(a,b-1),這裡用的是「分而治之」策略。
實現**如下
#include
using
namespace std;
string substring =
"";
string lcs
(string s1,string s2)
;int
main()
string lcs
(string s1,string s2)
else
if(s1[a]
==s2[b]
)else
else
}}
這種遞迴的方法由於多次重複計算,時間複雜度在最壞情況下達到o(2^n).
第二種方法是用迭代,通過動態規劃用表來儲存較短的字串的公共子串行長度,就避免的了大量重複計算,方法是上面遞迴方法的逆向執行,比如1313和
431254的最長公共子串行,列表
0 0 0 0 0 0 0
0 0 0 1 1 1 1
0 0 1 1 1 1 1
0 0 1 2 2 2 2
0 0 1 2 2 2 2
通過迴圈遍歷長寬為a+1,b+1的列表,第一行和第一列初始化為0,相同就填入左上加一,不同就填入左邊或上面格仔中較大的那個數,填滿**,**的最右下角即為所求最長公共子串行的長度。
下面是一開始寫的,可以得到正確長度但輸出的最長公共子串行有誤。
#include
using
namespace std;
string substring ="";
int maxelement =0;
intmax
(int
*p,int a,
int b)
;string lcs
(string s1,string s2)
;int
main()
string lcs
(string s1,string s2)
}for
(int i =
1; i < a +
1; i++)}
else}}
for(
int m =
0; m < a +
1;m++
) cout <<
"\n";}
return substring;
}int
max(
int*p,
int a,
int b)}}
if(max > maxelement)
else
if(max==maxelement)
return max;
}
經過手動測試,以上程式不能正確輸出最長公共子串行的原因在於它通過找到記錄列表中令每個最大值第一次出現的那個字元,並加入substring。但像這樣判斷是不完善的,第一次匹配到的元素是不會隨著更大更長的公共子串行的出現而替換的。因此通過乙個標誌陣列來記錄搜尋進行的方向,然後再由得到最長公共子串行的那一條路徑求得這兩個字串的最長公共子串行。
實現**
#include
using
namespace std;
string substring ="";
int symbol[
100]
[100];
void
lcs(string s1,string s2)
;string show
(int i,
int j, string x)
;int
main()
void
lcs(string s1,string s2)
}for
(int i =
1; i < a +
1; i++
)else
if(list[i -1]
[j]> list[i]
[j -1]
)else}}
for(
int m =
0; m < a +
1;m++
) cout <<
"\n";}
}string show
(int i,
int j,string x)
else
if(symbol[i]
[j]==1)
else
}
此方法的時間複雜度是o(m+n+m * n),包括求字元的m + n和求字串長度的m * n。 動態規劃 最長公共子串行 最長公共子串C 實現
對乙個序列x和另乙個序列y,兩者的最長公共序列是,兩者最長的公共子串是 最長公共子串要求連續 用動態規劃實現最重要的是要找到遞迴方程或者迭代方程,只要把這個方程找出來了,對著這個方程想個幾十分鐘,就可以把 寫出來,然後再拿例子測試,寫出來的 基本就沒問題了。也許你第一次接觸 如何將方程轉化為 的問題...
利用C 實現最長公共子串行與最長公共子串
一 問題描述 子串應該比較好理解,至於什麼是子串行,這裡給出乙個例子 有兩個母串 cnblogs belong 比如序列bo,bg,lg在母串cnblogs與belong中都出現過並且出現順序與母串保持一致,我們將其稱為公共子串行。最長公共子串行 longest common subs lcs 顧名...
最長公共子串行C
先來了解一下字串和子串行,乙個串的子串是指該串的乙個連續的區域性。如果不要求連續,則可稱為它的子串行。比如對串 abcdefg 而言,ab abd bdef 等都是它的子串行。特別地,乙個串本身,以及空串也是它的子串行。給出兩個字串,求出這樣的乙個最長的公共子串行的長度 子串行中的每個字元都能在兩個...