最长子序列之LCSlength算法详解.docx
- 文档编号:28422304
- 上传时间:2023-07-13
- 格式:DOCX
- 页数:8
- 大小:350.09KB
最长子序列之LCSlength算法详解.docx
《最长子序列之LCSlength算法详解.docx》由会员分享,可在线阅读,更多相关《最长子序列之LCSlength算法详解.docx(8页珍藏版)》请在冰豆网上搜索。
最长子序列之LCSlength算法详解
1003
1003CommonSubsequence
Asubsequenceofagivensequenceisthegivensequencewithsomeelements(possiblenone)leftout.GivenasequenceX=anothersequenceZ=isasubsequenceofXifthereexistsastrictlyincreasingsequenceofindicesofXsuchthatforallj=1,2,...,k,xij=zj.Forexample,Z=isasubsequenceofX=withindexsequence<1,2,4,6>.GiventwosequencesXandYtheproblemistofindthelengthofthemaximum-lengthcommonsubsequenceofXandY.
Theprograminputisfromatextfile.Eachdatasetinthefilecontainstwostringsrepresentingthegivensequences.Thesequencesareseparatedbyanynumberofwhitespaces.Theinputdataarecorrect.Foreachsetofdatatheprogramprintsonthestandardoutputthelengthofthemaximum-lengthcommonsubsequencefromthebeginningofaseparateline.
SampleInput
abcfbcabfcab
programmingcontest
abcdmnp
SampleOutput
4
2
0
C++语言:
Codee#8958
01#include
02#include
03usingnamespacestd;
04#defineN105
05intdp[N+1][N+1];
06charstr1[N],str2[N];
07intmaxx(inta,intb)
08{
09if(a>b)
10returna;
11returnb;
12}
13intLCSL(intlen1,intlen2)
14{
15inti,j;
16intlen=maxx(len1,len2);
17for(i=0;i<=len;i++)
18{
19dp[i][0]=0;dp[0][i]=0;
20}
21for(i=1;i<=len1;i++)
22for(j=1;j<=len2;j++)
23
24{
25if(str1[i-1]==str2[j-1])
26{
27dp[i][j]=dp[i-1][j-1]+1;
28}
29else
30{
31dp[i][j]=maxx(dp[i-1][j],dp[i][j-1]);
32}
33}
34returndp[len1][len2];
35}
36intmain()
37{
38while(cin>>str1>>str2)
39
40{
41intlen1=strlen(str1);
42intlen2=strlen(str2);
43cout< 44} 45return0; 46} 一、最长公共子序列(LongestCommonSubsequence: LCS) 设有两个序列A[1...m]和B[1...n],分别对A和B进行划分子序列 A[1]A[1..2]A[1..3]...A[1..m] B[1]B[1..2]B[1..3]...B[1..n] 依次求出A中的每个子序列(从A[1]开始)与B中每个子序列的最长公共子序列,并记录在数组C[m][n]中,C[i][j]表示A[1..i]和B[1..j]的最长公共子序列的长度。 递推公式如下: ①C[i][j]=0i=0orj=0 ②C[i][j]=C[i-1][j-1]+1i! =0andj! =0andA[i]=B[j] ③C[i][j]=max{C[i-1][j],C[i][j-1]}i! =0andj! =0andA[i]! =B[j] 路径记录: 记录路径即记录C[i][j]是怎么得来的,从递推公式②③知,C[i][j]的来源有三个: C[i-1][j-1],C[i-1][j],C[i][j-1]。 如果是从C[i-1][j-1]得来,那么A[i]=B[j],是最长公共子序列中的一个元素。 可以设置一个数组P[m][n]来记录当前的C[i][j]是怎么得来的,P[m][n]的取值只能有三种,分别记为123。 构造最长公共子序列: 用递归的方法,检查P[i][j],初始i=m,j=n 如果p[i][j]=1,则记录C[i][j],然后递归处理P[i-1][j-1] 如果P[i][j]=2,不记录,递归处理P[i-1][j] 如果P[i][j]=3,不记录,递推处理P[i][j-1] 直到i=0orj=0 时间复杂度: O(mn) C++语言: Codee#8959 01#include 02#include 03usingnamespacestd; 04#defineN105 05intdp[N+1][N+1]; 06charstr1[N],str2[N]; 07intmark[N+1][N+1]; 08intmaxx(inta,intb) 09{if(a>b)returna;returnb;} 10voidLCSL(intlen1,intlen2) 11{ 12inti,j; 13intlen=maxx(len1,len2); 14for(i=0;i<=len;i++) 15{ 16dp[i][0]=0;dp[0][i]=0; 17} 18for(i=1;i<=len1;i++) 19for(j=1;j<=len2;j++) 20{ 21if(str1[i-1]==str2[j-1]) 22{ 23dp[i][j]=dp[i-1][j-1]+1; 24mark[i][j]=1; 25} 26else 27{ 28inta=dp[i-1][j]; 29intb=dp[i][j-1]; 30dp[i][j]=maxx(a,b); 31if(a>=b) 32mark[i][j]=2; 33else 34mark[i][j]=3; 35} 36} 37} 38voidLCS(inti,intj) 39{ 40if(i==0||j==0) 41return; 42if(mark[i][j]==1) 43{ 44LCS(i-1,j-1); 45cout< 46} 47elseif(mark[i][j]==2) 48{ 49LCS(i-1,j); 50} 51else 52LCS(i,j-1); 53} 54intmain() 55{ 56while(cin>>str1>>str2) 57{ 58memset(mark,0,sizeof(mark)); 59intlen1=strlen(str1); 60intlen2=strlen(str2); 61LCSL(len1,len2); 62cout< 63if(dp[len1][len2]! =0) 64{ 65LCS(len1,len2); 66cout< 67} 68} 69system("pause"); 70return0;
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 最长 序列 LCSlength 算法 详解