日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

动态规划算法——最长公共子序列求法

發布時間:2023/12/8 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 动态规划算法——最长公共子序列求法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

????? 給定序列X={ X1,X2,....Xn }、Y={ Y1,Y2,...Ym }找出它們的最大子序列Z={ Z1,Z2,...Zk }比如:X={ A,B ,C,B,D,A,B }、Y={ B,D,C,A,B,A },它們的最大子序列

Z={ B,C,B,A}。

????? c[i][j]表示長度為i的X和長度為j的Y的最長子序列,c[0][j]=0,c[i][0]=0,任一序列與空序列的最長子序列為0。{ X1,X2,.....Xi }、{ Y1,Y2,....Yj },最大子序列長度分2種情況:Xi==Yj,則其長度是{ X1,X2,.....Xi-1 }、{ Y1,Y2,....Yj -1}最長子序列加1,即c[i][j]=c[i-1][j-1]+1,若Xi !=Yj,其長度為{ X1,X2,.....Xi -1}、{ Y1,Y2,....Yj }和

{ X1,X2,.....Xi }、{ Y1,Y2,....Yj -1}中最大的次序列長度,即:c[i][j]=max{ c[i-1][j]? ,c[i][j-1] }。

????????????????????????????????????????????????????? ?

dynamic.h

#pragma once #include<iostream> #include<vector> #include<string> using namespace std; class Lseq { public:void insertX(string x);//插入序列Xvoid insertY(string y);//插入序列Yvoid find();//尋找最大子序列void show();//輸出最大子序列void maxseq(int xi,int yj); private:vector<string> X;//輸入序列Xvector<string> Y;//輸入序列Yvector<string>Z;//最長公共子序列vector<vector<int> > c;//公共子序列的長度vector<vector<int> >path;//記錄路徑 };

dynamic.cpp

#include "stdafx.h" #include"dynamic.h" #include<iostream> #include<vector> #include<string> using namespace std;void Lseq::insertX(string x) {X.push_back(x); } void Lseq::insertY(string y) {Y.push_back(y); } void Lseq::find() {//分配c、path大小int nx=X.size();int ny=Y.size();c.resize(nx+1);path.resize(nx);for(int i=0;i<c.size();i++){c[i].resize(ny+1);if(i<nx)path[i].resize(ny);}for(int i=0;i<c.size();i++){c[i][0]=0; //Y長度為0,則公共的子序列長度為0}for(int i=0;i<ny+1;i++){c[0][i]=0;//X的長度為0,則公共的子序列長度為0}for(int i=0;i<nx;i++)for(int j=0;j<ny;j++){if(X[i]==Y[j]) {c[i+1][j+1]=c[i][j]+1;path[i][j]=0;//相等標記}else if(c[i+1][j]>c[i][j+1]){c[i+1][j+1]=c[i+1][j];path[i][j]=1; }else{c[i+1][j+1]=c[i][j+1];path[i][j]=2;}} } void Lseq::show() {find();int nx=X.size();int ny=Y.size();cout<<"最長子序列長度:"<<c[nx][ny]<<endl;cout<<"最長子序列為:";maxseq(nx-1,ny-1);//采用遞歸倒序的需找最長子序列cout<<endl; } void Lseq::maxseq(int xi,int yj) {if((xi<0)||(yj<0))return;if(path[xi][yj]==0){maxseq(xi-1,yj-1);cout<<X[xi]<<" ";}else if(path[xi][yj]==1)maxseq(xi,yj-1);elsemaxseq(xi-1,yj); }


Algorithm-dynamic2.cpp

// Algorithm-dynamic2.cpp : 定義控制臺應用程序的入口點。 // //實現最長公共序列 #include "stdafx.h" #include"dynamic.h" #include<iostream> #include<vector> #include<string> using namespace std; int _tmain(int argc, _TCHAR* argv[]) {Lseq s;//輸入序列Xs.insertX("A");s.insertX("B");s.insertX("C");s.insertX("B");s.insertX("D");s.insertX("A");s.insertX("B");//輸入序列Ys.insertY("B");s.insertY("D");s.insertY("C");s.insertY("A");s.insertY("B");s.insertY("A");//輸出最長子序列長度和最長子序列s.show();return 0; }


補充:對函數void maxseq(int xi,int yj);的說明,其主要功能是用于尋找最大的子序列。采用逆序查找,例中path 矩陣為:

X={ A,B ,C,B,D,A,B }、Y={ B,D,C,A,B,A }。開始:

(1)xi=6,yj=5;判斷path[6][5]==0?即X[6]與Y[5]是否相等,不相等。path[6][5]=2即xi=5,yj=5 這表明c[xi][yj]=c[xi-1][yj]

(2)在X={ A,B ,C,B,D,A }、Y={ B,D,C,A,B,A }中查找最大序列,path[5][5]==0,所以X[5]與Y[5]相等,X[5]為最大子序列中的一個,X[5]=A壓入棧中。xi=xi-1=4,yj=yj-1=4

(3)X={ A,B ,C,B,D }、Y={ B,D,C,A,B }中查找最大序列,path[4][4]==2,xi=xi-1=3,yj=yj=4?

(4)X={ A,B ,C,B }、Y={ B,D,C,A,B }中查找最大序列,path[3][4]==0,X[3]為最大子序列中一個,X[3]=B壓入棧中,xi=xi-1=2,yj=yj-1=3

(5)X={ A,B ,C }、Y={ B,D,C,A }中查找最大序列,path[2][3]==1,xi=xi=2,yj=yj-1=2

(6)X={ A,B ,C }、Y={ B,D,C }中查找最大序列,path[2][2]==0,X[2]為最大子序列中一個,X[2]=C壓入棧中,xi=xi-1=1,yj=yj-1=1;

(7)X={ A,B? }、Y={ B,D }中查找最大序列,path[1][1]==1,xi=xi=1,yj=yj-1=0;

(8)X={ A,B? }、Y={ B }中查找最大序列,path[1][0]==0,X[1]為最大子序列中一個,X[1]=B壓入棧中,xi=xi-1=0,yj=yj-1=-1;

(9)yj<0返回,則最大子序列查找到,輸出:B C B A

總結

以上是生活随笔為你收集整理的动态规划算法——最长公共子序列求法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。