版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、精選優(yōu)質(zhì)文檔-傾情為你奉上問題描述:一個給定序列的子序列是在該序列中刪去若干元素后得到的序列。確切地說,若給定序列X= x1, x2, xm,則另一序列Z= z1, z2, zk是X的子序列是指存在一個嚴格遞增的下標序列 i1, i2, ik,使得對于所有j=1,2,k有 Xij=Zj。例如,序列Z=B,C,D,B是序列X=A,B,C,B,D,A,B的子序列,相應(yīng)的遞增下標序列為2,3,5,7。給定兩個序列X和Y,當(dāng)另一序列Z既是X的子序列又是Y的子序列時,稱Z是序列X和Y的公共子序列。例如,若X= A, B, C, B, D, A, B和Y= B, D, C
2、, A, B, A,則序列B,C,A是X和Y的一個公共子序列,序列B,C,B,A也是X和Y的一個公共子序列。而且,后者是X和Y的一個最長公共子序列,因為X和Y沒有長度大于4的公共子序列。給定兩個序列X= x1, x2, , xm和Y= y1, y2, , yn,要求找出X和Y的一個最長公共子序列。 問題解析:設(shè)X= A, B, C, B, D, A, B,Y= B, D, C, A, B, A。求X,Y的最長公共子序列最容易想到的方法是窮舉法。對X的多有子序列,檢查它是否也是Y的子序列,從而確定它是否為X和Y的公共子序列。由集合的性質(zhì)知
3、,元素為m的集合共有2m個不同子序列,因此,窮舉法需要指數(shù)級別的運算時間。進一步分解問題特性,最長公共子序列問題實際上具有最優(yōu)子結(jié)構(gòu)性質(zhì)。 設(shè)序列X=x1,x2,xm和Y=y1,y2,yn的最長公共子序列為Z=z1,z2,zk。則有: (1)若xm=yn,則zk=xm=yn,且zk-1是Xm-1和Yn-1的最長公共子序列。 (2)若xm!=yn且zk!=xm,則Z是Xm-1和Y的最長公共子序列。
4、; (3)若xm!=yn且zk!=yn,則Z是X和Yn-1的最長公共子序列。 其中,Xm-1=x1,x2xm-1,Yn-1=y1,y2yn-1,Zk-1=z1,z2zk-1。 遞推關(guān)系:用cij記錄序列Xi和Yj的最長公共子序列的長度。其中,Xi=x1,x2xi,Yj=y1,y2yj。當(dāng)i=0或j=0時,空序列是xi和yj的最長公共子序列。此時,cij=0;當(dāng)i,j>0,xi=yj時,cij=ci-1j-1+1;當(dāng)i,j>0,xi!=yj時,cij=
5、maxcij-1,ci-1j,由此建立遞推關(guān)系如下: 構(gòu)造最優(yōu)解:由以上分析可知,要找出X=x1,x2,xm和Y=y1,y2,yn的最長公共子序列,可以按一下方式遞歸進行:當(dāng)xm=yn時,找出xm-1和yn-1的最長公共子序列,然后在尾部加上xm(=yn)即可得X和Y的最長公共子序列。當(dāng)Xm!=Yn時,必須解兩個子問題,即找出Xm-1和Y的一個最長公共子序列及X和Yn-1的一個最長公共子序列。這兩個公共子序列中較長者為X和Y的最長公共子序列。設(shè)數(shù)組bij記錄cij的值由哪一個子
6、問題的解得到的,從bmn開始,依其值在數(shù)組b中搜索,當(dāng)bij=1時,表示Xi和Yj的最長公共子序列是由Xi-1和Yj-1的最長公共子序列在尾部加上xi所得到的子序列。當(dāng)bij=2時,表示Xi和Yj的最長公共子序列與Xi-1和Yj-1的最長公共子序列相同。當(dāng)bij=3時,表示Xi和Yj的最長公共子序列與Xi和Yj-1的最長公共子序列相同。 代碼如下:cpp 1. /3d3-1 最長公共子序列問題 2. #include "stdafx.h" 3
7、. #include <iostream> 4. using namespace std; 5. 6. const int M = 7; 7. const int N = 6; 8. 9. void output(char *s,int n); 10. void
8、160;LCSLength(int m,int n,char *x,char *y,int *c,int *b); 11. void LCS(int i,int j,char *x,int *b); 12. 13. int main() 14. 15. /X=A,B,C,B,D,A,B 16.
9、 /Y=B,D,C,A,B,A 17. char x = ' ','A','B','C','B','D','A','B' 18. char y = ' ','B','
10、D','C','A','B','A' 19. 20. int *c = new int *M+1; 21. int *b = new int *M+1; 22. for(int i=0
11、;i<=M;i+) 23. 24. ci = new intN+1; 25. bi = new intN+1; 26.
12、 27. 28. cout<<"序列X:"<<endl; 29. output(x,M); 30. cout<<"序列Y:"<<endl; 31.
13、 output(y,N); 32. 33. LCSLength(M,N,x,y,c,b); 34. 35. cout<<"序列X、Y最長公共子序列長度為:"<<cMN<<endl; 36. cout<<"序列X、Y最長公共子序列為:"<&
14、lt;endl; 37. LCS(M,N,x,b); 38. cout<<endl; 39. 40. 41. void output(char *s,int n) 42. 43. for(int i=1; i<=n;
15、i+) 44. 45. cout<<si<<" " 46. 47. cout<<endl; 48. 49. 50. void
16、0;LCSLength(int m,int n,char *x,char *y,int *c,int *b) 51. 52. int i,j; 53. 54. for(i=1; i<=m; i+) 55.
17、160;ci0 = 0; 56. for(i=1; i<=n; i+) 57. c0i = 0; 58. 59. for(i=1; i<=m; i+) 60.
18、0; 61. for(j=1; j<=n; j+) 62. 63. if(xi=yj) 64.
19、160; 65. cij=ci-1j-1+1; 66. bij=1;
20、0;67. 68. else if(ci-1j>=cij-1) 69. 70. &
21、#160; cij=ci-1j; 71. bij=2; 72. &
22、#160; 73. else 74. 75.
23、60; cij=cij-1; 76. bij=3; 77. 78.
24、; 79. 80. 81. 82. void LCS(int i,int j,char *x,int *b) 83. 84. if(i=0 | j=0) 85. 86.
25、60; return; 87. 88. if(bij=1) 89. 90. LCS(i-1,j-1,x,b); 91.
26、0; cout<<xi<<" " 92. 93. else if(bij=2) 94. 95. LCS(i-1,j,x,b); 96.
27、 97. else 98. 99. LCS(i,j-1,x,b); 100. 101. &
28、#160; LCSLength函數(shù)在計算最優(yōu)值時,分別迭代X,Y構(gòu)造數(shù)組b,c。設(shè)數(shù)組每個元素單元計算耗費時間O(1),則易得LCSLength的時間復(fù)雜度為O(mn)。在算法LCS中,依據(jù)數(shù)組b的值回溯構(gòu)造最優(yōu)解,每一次遞歸調(diào)用使i,或j減小1。從而算法的計算時間為O(m+n)。LCS的回溯構(gòu)造最優(yōu)解過程如下圖所示: 算法的改進:對于一個具體問題,按照一般的算法設(shè)計策略設(shè)計出的算法,往往在算法的時間和空間需求上還可以改進。這種改進,通常是利用
29、具體問題的一些特殊性。例如,在算法LCS_length和LCS中,可進一步將數(shù)組b省去。事實上,數(shù)組元素ci,j的值僅由ci-1j-1,ci-1j和cij-1三個值之一確定,而數(shù)組元素bij也只是用來指示cij究竟由哪個值確定。因此,在算法LCS中,我們可以不借助于數(shù)組b而借助于數(shù)組c本身臨時判斷cij的值是由ci-1j-1,ci-1j和cij-1中哪一個數(shù)值元素所確定,代價是(1)時間。既然b對于算法LCS不是必要的,那么算法LCS_length便不必保存它。這一來,可節(jié)省(mn)的空間,而LCS_length和LCS所需要的時間分別仍然是(mn)和(m+n)。另外,如果只需要計算最長公共子
30、序列的長度,則算法的空間需求還可大大減少。事實上,在計算cij時,只用到數(shù)組c的第i行和第i-1行。因此,只要用2行的數(shù)組空間就可以計算出最長公共子序列的長度。更進一步的分析還可將空間需求減至min(m, n)。cpp 1. /3d3-2 最長公共子序列問題 2. #include "stdafx.h" 3. #include <iostream> 4. using namespace std;
31、0; 5. 6. const int M = 7; 7. const int N = 6; 8. 9. void output(char *s,int n); 10. void LCSLength(int m,int n,char *x,char *y,int *c); 11. vo
32、id LCS(int i,int j,char *x,int *c); 12. 13. int main() 14. 15. /X=A,B,C,B,D,A,B 16. /Y=B,D,C,A,B,A 17. char x =
33、9; ','A','B','C','B','D','A','B' 18. char y = ' ','B','D','C','A','B','A' 19. 20. &
34、#160;int *c = new int *M+1; 21. for(int i=0;i<=M;i+) 22. 23. ci = new intN+1; 24.
35、; 25. 26. cout<<"序列X:"<<endl; 27. output(x,M); 28. cout<<"序列Y:"<<endl; 29.
36、; output(y,N); 30. 31. LCSLength(M,N,x,y,c); 32. 33. cout<<"序列X、Y最長公共子序列長度為:"<<cMN<<endl; 34. cout<<"序列X、Y最長公共子序列為:
37、"<<endl; 35. LCS(M,N,x,c); 36. cout<<endl; 37. 38. 39. void output(char *s,int n) 40. 41. for(int i=1; i&l
38、t;=n; i+) 42. 43. cout<<si<<" " 44. 45. cout<<endl; 46. 47. 4
39、8. void LCSLength(int m,int n,char *x,char *y,int *c) 49. 50. int i,j; 51. 52. for(i=1; i<=m; i+) 53.
40、60;ci0 = 0; 54. for(i=1; i<=n; i+) 55. c0i = 0; 56. 57. for(i=1; i<=m; i+) 58.
41、; 59. for(j=1; j<=n; j+) 60. 61. if(xi=yj) 62.
42、60; 63. cij=ci-1j-1+1; 64. 65. &
43、#160; else if(ci-1j>=cij-1) 66. 67. cij=ci-1j; 68
44、. 69. else 70. 71.
45、 cij=cij-1; 72. 73. 74. 75.
46、0;76. 77. void LCS(int i,int j,char *x,int *c) 78. 79. if(i=0 | j=0) 80. 81. return; 82.
47、; 83. if(cij=ci-1j-1+1) 84. 85. LCS(i-1,j-1,x,c); 86. cout<<xi<<" "
48、; 87. 88. else if(ci-1j>=cij-1) 89. 90. LCS(i-1,j,x,c); 91. 92.
49、60;else 93. 94. LCS(i,j-1,x,c); 95. 96. 運行結(jié)果如下:
50、160; 從運行結(jié)果中可以看出,算法LCS回溯算法僅僅打印了其中一條最大公共子序列,如果存在多條公共子序列的情況下。怎么解決?對bij二維數(shù)組的取值添加一種可能,等于4,這代表了我們說的這種多支情況,那么回溯的時候可以根據(jù)這個信息打印更多可能的選擇。你從(7,6)點開始按bij的值指示的方向回溯,把所有的路徑遍歷一遍,如果是能達到起點(1,1)的路徑,就是LCS了,有多少條打印多少條??墒?,在回溯路徑的時候,如果采用一般的全搜索,會進行了很多無用功。即重復(fù)了很多,且會遍歷了一些無效路徑,因為這些路徑最終不會到達終點(1,1),因此加大算法復(fù)雜度和
51、時間消耗。 博文給出了一種"矩行搜索"的解決辦法降低了算法的復(fù)雜度。算法主要是利用兩個棧store,print,一個用來儲存節(jié)點,一個用來打印節(jié)點。 棧的實現(xiàn)代碼如下(文件Stack.h):cpp 1. /* 2. 頭文件-head file 3. */ 4. 5.
52、template <class T> 6. class StackNode 7. public: 8. T data; 9. StackNode *next; 10. ;
53、60;11. 12. template <class T> 13. class Stack 14. public: 15. Stack(void):top(NULL) 16. bool IsEmp
54、ty(void) const return top=NULL; 17. void Push(const T data); 18. bool Pop(T *data); 19. &
55、#160;bool Peek(T *data) const; 20. StackNode<T> * GetStackNode(); 21. private: 22. StackNode<T> *top;
56、0; 23. ; 24. 25. template <class T> 26. StackNode<T> * Stack<T>:GetStackNode() 27. return top; 28. 29. 30. template <class T> &
57、#160;31. void Stack<T>:Push(const T data) 32. StackNode<T> *node = new StackNode<T>(); 33. node->data = data; 34. node->next
58、160;= top; 35. top = node; 36. 37. 38. template <class T> 39. bool Stack<T>:Peek(T *data) const 40. if(IsEmpty() return fa
59、lse; 41. *data = top->data; 42. return true; 43. 44. 45. template <class T> 46. bool Stack<T>:Pop(T *data) 47.
60、 if(IsEmpty() return false; 48. *data = top->data; 49. StackNode<T> *node = top; 50. top = top->next; 51.
61、0; delete(node); 52. return true; 53. 所有最長公共子序列問題LCS 矩陣搜索代碼如下:cpp 1. /3d3-3 所有最長公共子序列問題LCS 矩陣搜索 2. #include "stdafx.h" 3. #include
62、160;"stack.h" 4. #include <iostream> 5. using namespace std; 6. 7. typedef int *Matrix; 8. const int M = 7; 9. const int N = 6; 10.
63、60;11. typedef struct _Element 12. 13. int lcslen;/當(dāng)前節(jié)點的LCS長度 14. int row;/當(dāng)前節(jié)點的行坐標 15. int col;/當(dāng)前節(jié)點的列坐標 16. Element; 17. 1
64、8. void output(char *s,int n); 19. 20. Element CreateElement(int nlen, int row, int col); 21. 22. Matrix GreateMatrix(int row, int col); 23. void DeleteMatrix(Matrix p,
65、 int row); 24. 25. void PrintStack(Stack<Element> *ps, char *str, int len); 26. void SearchE(Matrix pb, int curposx, int curposy, int &eposx, int &eposy, int
66、 ntype); 27. 28. void LCSLength(int m,int n,char *x,char *y,Matrix pc,Matrix pb); 29. void LCS(char *x, Matrix pc, Matrix pb, int row, int col);/矩陣搜索回溯 30.
67、60;31. 32. int main() 33. char x = ' ','A','B','C','B','D','A','B' 34. char y = ' ','B','
68、D','C','A','B','A' 35. 36. Matrix b = GreateMatrix(M, N); 37. Matrix c = GreateMatrix(M, N); 38. 39.
69、 LCSLength(M,N,x,y,c,b); 40. 41. cout<<"序列X:"<<endl; 42. output(x,M); 43. cout<<"序列Y:"<<endl; 44. o
70、utput(y,N); 45. 46. cout<<"序列X、Y最長公共子序列長度為:"<<cMN<<endl; 47. cout<<"序列X、Y最長公共子序列為:"<<endl; 48. 49. LCS(x,c,b,M,N); &
71、#160;50. 51. DeleteMatrix(b,M); 52. DeleteMatrix(c,M); 53. 54. return 0; 55. 56. 57. void output(char *s,int n) 58.
72、 59. for(int i=1; i<=n; i+) 60. 61. cout<<si<<" " 62. 63.
73、160;cout<<endl; 64. 65. 66. Element CreateElement(int nlen, int row, int col) 67. 68. Element ele; 69. ele.lcslen = nlen;
74、;70. ele.col = col; 71. ele.row = row; 72. return ele; 73. 74. 75. Matrix GreateMatrix(int row, int col) 76.
75、 77. Matrix p = new int *row+1; 78. for(int i=0;i<=row;i+) 79. 80. pi = ne
76、w intcol+1; 81. 82. return p; 83. 84. 85. void DeleteMatrix(Matrix p, int row) 86. 87. for(int i=0;i<=r
77、ow;i+) 88. 89. delete pi; 90. 91. 92. delete p; 93. 94.
78、60;95. void PrintStack(Stack<Element> *s,char *str,int len) 96. 97. if(s = NULL | str = NULL) 98. return; 99.
79、; 100. StackNode<Element> *sn = s->GetStackNode(); 101. 102. while(sn!=NULL && sn->data.row<=len) 103. 104.
80、60; cout<<strsn->data.row<<" " 105. sn = sn->next; 106. 107. 108. cout<<en
81、dl; 109. 110. 111. void SearchE(Matrix pb, int curposx, int curposy, int &eposx, int &eposy, int ntype) 112. 113. switch(pbcurposxcurposy)
82、114. 115. case 1: 116. eposx = curposx; 117. eposy = curposy; 118. &
83、#160; return; 119. case 2: 120. SearchE(pb, curposx-1, curposy, eposx, eposy, ntype); 121. bre
84、ak; 122. case 3: 123. SearchE(pb, curposx, curposy-1, eposx, eposy, ntype); 124. break; 125. &
85、#160; case 4: 126. if(ntype = 0) 127. /搜索e1點,如過碰到分叉點,向上繼續(xù)搜索 128.
86、160; SearchE(pb, curposx-1, curposy, eposx, eposy, ntype); 129. else 130. /搜索e2點,如過碰到分叉點,向左繼續(xù)搜索 131.
87、0; SearchE(pb, curposx, curposy-1, eposx, eposy, ntype); 132. break; 133. 134. 135. 136. voi
88、d LCSLength(int m,int n,char *x,char *y,Matrix pc,Matrix pb) 137. 138. int i,j; 139. 140. for(i=1; i<=m; i+) 141.
89、0; pci0 = 0; 142. for(i=1; i<=n; i+) 143. pc0i = 0; 144. 145. for(i=1; i<=m; i+) 146.
90、 147. for(j=1; j<=n; j+) 148. 149. if(xi=yj) 150.
91、 151. pcij=pci-1j-1+1; 152.
92、60; pbij=1; 153. 154. else if(pci-1j>pcij-1) 155.
93、; 156. pcij=pci-1j; 157. pbij=2; 158. &
94、#160; 159. else if(pci-1j<pcij-1) 160. 161.
95、0; pcij=pcij-1; 162. pbij=3; 163.
96、; 164. else 165. 166.
97、0;pcij = pcij-1;/由左節(jié)點或上節(jié)點轉(zhuǎn)移而來 167. pbij = 4;/標記為4 168. 169.
98、 170. 171. 172. 173. void LCS(char *x, Matrix pc, Matrix pb, int row, int col) 174. 175. if(x =
99、160;NULL | pc = NULL | pb = NULL) 176. return; 177. 178. Stack<Element> store, print;/構(gòu)造兩個棧store,print
100、179. Element storetop;/store棧的棧頂節(jié)點 180. Element element;/臨時變量 181. Element virtualnode;/虛擬節(jié)點 182. int ntoplen;/保存store棧頂節(jié)點的LCS長度 183.
101、 int ex1,ey1,ex2,ey2;/矩形搜索的兩個節(jié)點的坐標 184. int i,j; 185. 186. virtualnode = CreateElement(pcrowcol+1, row+1, col+1); 187. 188.
102、store.Push(virtualnode);/壓入虛擬節(jié)點到store 189. 190. while(!store.IsEmpty() 191. 192. store.Pop(&storetop); 193.
103、; if(storetop.row = 1 | storetop.col = 1)/如果是邊界節(jié)點 194. 195. print.Push(storetop); 196.
104、 PrintStack(&print, x, row);/打印print棧里面除虛擬節(jié)點之外的所有節(jié)點 197. store.Peek(&element); 198.
105、60; ntoplen = element.lcslen;/當(dāng)前store的棧頂節(jié)點的LCS長度 199. 200. /*彈出print棧中所有LCS長度小于等于ntoplen的節(jié)點*/ 201.
106、160;while(print.Peek(&element) && element.lcslen<=ntoplen) 202. 203. print.Pop(&element); 204. 205. 206. else 207.
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 化工行業(yè)水處理及安全相關(guān)知識AA001單元測試試卷
- 財務(wù)辦公室制度管理制度
- 落實收款與入賬制度
- 醫(yī)療質(zhì)量考核與持續(xù)改進實施方案
- 2026年上半年黑龍江事業(yè)單位聯(lián)考省地震局招聘2人參考考試題庫附答案解析
- 2026福建泉州石獅市自然資源局招聘編外工作人員1人備考考試題庫附答案解析
- 2026新疆博爾塔拉州博樂市中西醫(yī)結(jié)合醫(yī)院面向全市選聘義務(wù)行風(fēng)監(jiān)督員備考考試題庫附答案解析
- 2026湖北武漢市江岸區(qū)事業(yè)單位招聘財務(wù)人員1人備考考試題庫附答案解析
- 2026中國人民警察大學(xué)招聘27人參考考試試題附答案解析
- 2026年上半年黑龍江省林業(yè)科學(xué)院事業(yè)單位公開招聘工作人員55人參考考試題庫附答案解析
- 2025漂浮式海上風(fēng)電場工程可行性研究報告編制規(guī)程
- 路基工程施工方案(2016.11.6)
- UL676標準中文版-2019水下燈具和接線盒UL標準中文版
- 醫(yī)學(xué)教材 常見心律失常診治(基層醫(yī)院培訓(xùn))
- 體溫單模板完整版本
- 武漢市2024屆高中畢業(yè)生二月調(diào)研考試(二調(diào))英語試卷(含答案)
- 天然美肌無添加的護膚品
- 湖南省長沙市外國語學(xué)校 2021-2022學(xué)年高一數(shù)學(xué)文模擬試卷含解析
- 3D車載蓋板玻璃項目商業(yè)計劃書
- 阿米巴經(jīng)營管理培訓(xùn)課件
- 我國的宗教政策-(共38張)專題培訓(xùn)課件
評論
0/150
提交評論