国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

C++ 求解最長(zhǎng)公共子序列(不僅僅求出其大?。ê?jiǎn)單易懂?。。。▌?dòng)態(tài)規(guī)劃)

這篇具有很好參考價(jià)值的文章主要介紹了C++ 求解最長(zhǎng)公共子序列(不僅僅求出其大?。ê?jiǎn)單易懂?。。。▌?dòng)態(tài)規(guī)劃)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

求解兩個(gè)數(shù)組的最長(zhǎng)公共子序列我們需要用到的知識(shí)點(diǎn)有:動(dòng)態(tài)規(guī)劃dp,遞歸算法

先來(lái)說(shuō)說(shuō)動(dòng)態(tài)規(guī)劃dp 很多初學(xué)者在學(xué)習(xí)動(dòng)態(tài)規(guī)劃的時(shí)候總是百思不得其解,什么是動(dòng)態(tài)規(guī)劃呢,其實(shí)總結(jié)來(lái)說(shuō)就是程序?qū)⒂?jì)算過(guò)的結(jié)果記錄下來(lái),在下次使用到這條記錄的時(shí)候不需要再次計(jì)算,而可以直接使用,這樣看來(lái)是不是節(jié)省了很大的時(shí)間開(kāi)銷呢!

動(dòng)態(tài)規(guī)劃解決問(wèn)題一般套路可以分為兩步,1:自頂向下的分析問(wèn)題 2:自底向上的解決問(wèn)題

為什么要自頂向下的分析問(wèn)題呢? 我們要知道問(wèn)題在多數(shù)值的情況下往往會(huì)具有一般性。

而自底向上的解決問(wèn)題則是因?yàn)閿?shù)據(jù)是從最底的數(shù)據(jù)開(kāi)始記錄,由少的數(shù)值計(jì)算得出多的數(shù)值。

我們可以用蓋房子為例子,工程師是負(fù)責(zé)設(shè)計(jì)架構(gòu)的,一般是從房子的頭部開(kāi)始向下設(shè)計(jì),而建造房子則是需要從最底部開(kāi)始搭建,所以自頂向下的設(shè)計(jì),自底向上的解決。

現(xiàn)在回到我們的問(wèn)題上,求兩個(gè)字符串的最長(zhǎng)序列,假設(shè)第一個(gè)字符串為S1,字符長(zhǎng)度為i,第二個(gè)字符串為S2,字符長(zhǎng)度為j。建立二維數(shù)組dp[i+1][j+1],dp[i][j]的意思為第一個(gè)字符串的前i個(gè)與第二個(gè)字符串的前j個(gè)的最長(zhǎng)子序列。我們自頂向下的分析問(wèn)題即從S1的最后一個(gè)即第i個(gè)與S2的最后一個(gè)即第j個(gè)進(jìn)行判斷。顯而易見(jiàn)可以看出假如S1[i]==S2[j]相等的話那么i與j判斷完畢,接下來(lái)就從i-1與j-1開(kāi)始判斷(因?yàn)閕與j判斷完畢就往前判斷)故dp[i][j]=dp[i-1][j-1]+1。

假如S1[i]==S2[j]不相等的話,那么會(huì)出現(xiàn)兩種情況,要知道最大子序列是兩者共有的,那么i和j不相等,他們之中一定有一個(gè)不在子序列當(dāng)中,所以要么i不在,要么j不在,i不在那么我們就從i-1開(kāi)始找,j不在我們就從j-1開(kāi)始找。故dp[i][j]=max(dp[i-1][j],dp[i][j-1])。

代碼如下:

	for(int p=1;p<=i;p++)// i為S1的長(zhǎng)度       p,q皆從1開(kāi)始往后面循環(huán)                          
	{
		for(int q=1;q<=j;q++) //j為S2的長(zhǎng)度      自底向上解決問(wèn)題
		{
			
			if(s1[p-1]==s2[q-1])  //字符串從0開(kāi)始 這里容易出錯(cuò)
			{
				dp[p][q]=dp[p-1][q-1]+1;
			}
			else
			{
				dp[p][q]=max(dp[p-1][q],dp[p][q-1]);
			}
			
		}
	}

這樣我們就可以得到最長(zhǎng)子序列的長(zhǎng)度了,可以這樣我們無(wú)法得知最長(zhǎng)子序列到底是什么樣的?

想要得出這個(gè)結(jié)果,我們就需要使用遞歸來(lái)解決。

在先前我們已經(jīng)得出了dp數(shù)組的完整數(shù)值,我們可以使用dp數(shù)組的值遞歸來(lái)解決,我們先準(zhǔn)備一個(gè)空數(shù)組,假如S1[i]==S[j],那么我們就可以直接把這個(gè)值記錄到數(shù)組里,假如他們不相等,那么就是上面的情況了分別是i不在和j不在。具體我們已經(jīng)通過(guò)dp計(jì)算出來(lái)了即dp[i][j]==dp[i-1][j]那么就是i不在序列中,我們從S1的第1個(gè)到i-1個(gè)與S2的第1個(gè)到第j個(gè)開(kāi)始尋找。dp[i][j]==dp[i][j-1]那么就是j不在序列中,我們從S1的第1個(gè)到i個(gè)與S2的第1個(gè)到第j-1個(gè)開(kāi)始尋找。這樣重復(fù)遞歸,當(dāng)i等于0或者j為0時(shí)停止遞歸。

代碼如下:

void found(string a,string b,int i,int j,char rem[],int dp[][100]){
 	if(i==0 ||j==0){
 		
	 return;
 	
	 }
 	if(a[i-1]==b[j-1])
 	{
 		rem[m]=a[i-1];
 		m++;
 		found(a,b,i-1,j-1,rem,dp);
	 }
	 else{
	 	if(dp[i][j]==dp[i-1][j])
	 	found(a,b,i-1,j,rem,dp);
	 	else if (dp[i][j]==dp[i][j-1])
	 	found(a,b,i,j-1,rem,dp);
	 	
	 }
		
	}

所以總體的代碼為:

#include<iostream>
using namespace std;
#include<algorithm>
#include <cstring>
int m;   //m用來(lái)記錄兩個(gè)字符串相等的個(gè)數(shù)
void found(string a,string b,int i,int j,char rem[],int dp[100][100]);

int main()
{
	string s1;
	string s2;
	int i,j;
	cout<<"請(qǐng)輸入第一個(gè)字符串:"; 
	cin>>s1;
	cout<<"請(qǐng)輸入第二個(gè)字符串:"; 
	cin>>s2;
	i=s1.length();
	j=s2.length();
	int dp[i+1][100];
	char rem[max(i,j)];
	memset(dp,0,sizeof(dp));
	for(int p=1;p<=i;p++)
	{
		for(int q=1;q<=j;q++)
		{
			
			if(s1[p-1]==s2[q-1])
			{
				dp[p][q]=dp[p-1][q-1]+1;
			}
			else
			{
				dp[p][q]=max(dp[p-1][q],dp[p][q-1]);
			}
			
		}
	}
    
	cout<<"最大子序列的個(gè)數(shù)為:"<<dp[i][j]<<endl;
	
	found(s1,s2,i,j,rem,dp);
	for(int g=m-1;g>=0;g--)     //因?yàn)槭悄嫘虮4娴乃孕枰嫘蜉敵?	{
		cout<<rem[g];
	}

	
}
void found(string a,string b,int i,int j,char rem[],int dp[][100]){
 	if(i==0 ||j==0){
 		
	 return;
 	
	 }
 	if(a[i-1]==b[j-1])
 	{
 		rem[m]=a[i-1];
 		m++;
 		found(a,b,i-1,j-1,rem,dp);
	 }
	 else{
	 	if(dp[i][j]==dp[i-1][j])
	 	found(a,b,i-1,j,rem,dp);
	 	else if (dp[i][j]==dp[i][j-1])
	 	found(a,b,i,j-1,rem,dp);
	 	
	 }
		
	}

運(yùn)行結(jié)果案例如下:

動(dòng)態(tài)規(guī)劃最長(zhǎng)公共子序列問(wèn)題c++,c++,算法,開(kāi)發(fā)語(yǔ)言

?文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-765746.html

?

?

到了這里,關(guān)于C++ 求解最長(zhǎng)公共子序列(不僅僅求出其大?。ê?jiǎn)單易懂!?。。▌?dòng)態(tài)規(guī)劃)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包