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

動(dòng)態(tài)規(guī)劃——最長(zhǎng)公共子序列

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

先來講解以下什么是最長(zhǎng)公共子序列。最長(zhǎng)公共子序列不是最長(zhǎng)相同字符串,有點(diǎn)相似但不一樣,來舉個(gè)簡(jiǎn)單的例子,有字符串s1=bcdea,s2=abce,最長(zhǎng)相同字符串是bc,最大公共部分是2;而最長(zhǎng)公共子序列則是bce,最大公共部分是3??梢钥闯?,公共子序列不需要連續(xù)相等,有相同的序列即可。

明白了概念之后,我們來看一下題目。


2-1 兩個(gè)字符串的所有最長(zhǎng)公共子序列 (轉(zhuǎn)自PTA)

求兩個(gè)字符串的所有最長(zhǎng)公共子序列。

輸入格式:

輸入長(zhǎng)度≤100的兩個(gè)字符串。

輸出格式:

輸出兩個(gè)字符串的所有最長(zhǎng)公共子序列,若最長(zhǎng)公共子序列多于1個(gè),則將所有子序列按字典序從小到大排序后輸出。

輸入樣例1:

ABCBDAB
BDCABA

輸出樣例1:

BCAB
BCBA
BDAB

輸入樣例2:

ABACDEF
PGHIK

輸出樣例2:

NO

讀完題目之后還有點(diǎn)懵的話,那就先聽一下我的思路。本題要輸出的是最長(zhǎng)公共子序列,可能的情況可以分為三種:不存在、只有一條和有多條。如果我們逐個(gè)去枚舉的話,如果遇到存在多條的情況,是很容易出錯(cuò)并且漏選。那我們可以先求出其最長(zhǎng)的長(zhǎng)度是多少,再用回溯法,一一找出。

求最大公共子序列的長(zhǎng)度

string s1, s2;
int arr[101][101]={0};//動(dòng)態(tài)規(guī)劃表
set <string> lsc_s;
int lsc_max(int m, int n)//求出最大公共子序列的長(zhǎng)度 
{
	for(int i=1;i<=m;i++)
	{
		for(int j=1;j<=n;j++)
		{
			if(s1[i-1]==s2[j-1])arr[i][j]=arr[i-1][j-1]+1;
			else arr[i][j]=max(arr[i-1][j],arr[i][j-1]);
		}
	}
	return arr[m][n];
}

s1、s2是要輸入的兩個(gè)字符串,set是集合(后面再講)。我們?cè)趺磥肀容^呢,設(shè)立一個(gè)二維表,即上面的arr,字符串s1為縱列,字符串s2為橫行。

動(dòng)態(tài)規(guī)劃——最長(zhǎng)公共子序列

首先拿出s1中的第一個(gè)字符和s2中逐一比較,可得出b行b列的意思是s1中b和s2中ab比較,有1個(gè)公共的,故為1;b行c列是s1中b和s2中abc比較,也只有一個(gè)公共,也為1;再舉一個(gè)例子,e行e列是s1中bcde和s2中abce比較,因?yàn)閑和e相同,并且前面s1中bcd和s2中abc比較時(shí)已經(jīng)有兩個(gè)公共的了,所以要2+1=3;以此類推,可得出此表,同時(shí)我們也可以得出一條遞推公式,即

if s1[i]==s2[j],arr[i][j]=arr[i-1][j-1]+1;

else arr[i][j]=max{ arr[i][j-1], arr[i-1][j] };

即可得出最長(zhǎng)公共子序列的最大長(zhǎng)度arr[i][j]。下一步就可根據(jù)回溯法來獲取公共子序列的所有序列并打印。

打印所有最長(zhǎng)公共子序列

void lsc_print(int i, int j, string str)
{
	while(i>0&&j>0)
	{
		if(s1[i-1]==s2[j-1])
		{
			i--;
			j--;
			str=s1[i]+str;
		}
		else
		{
			if(arr[i-1][j]>arr[i][j-1])i--;
			else if(arr[i-1][j]<arr[i][j-1])j--;
			else 
			{
				lsc_print(i-1,j,str);
				lsc_print(i,j-1,str);
				return;
			}
		}
	}
	if(str.length())lsc_s.insert(str);
}

從arr[i][j]開始回溯,當(dāng)s1[i-1]==s2[j-1]時(shí),說明此公共子序列中包括這個(gè)元素,即可把這個(gè)元素加入到臨時(shí)變量str中(頭插法),因?yàn)槭腔厮?,滿足條件的元素在前面;當(dāng)s1[i-1]!=s2[j-1]時(shí),說明arr[i][j]是由arr[i-1][j]或者arr[i][j-1]繼承而來,所以可以判斷這兩個(gè)哪個(gè)比較大,就跑去那邊,當(dāng)兩邊一樣大的時(shí)候,說明可能存在不同的最長(zhǎng)子序列,所以可以進(jìn)行遞歸分別求解。當(dāng)回溯完成后,把str放入到set容器中儲(chǔ)存起(為什么用set不用數(shù)組,因?yàn)轭}目要求按字典序從小到大輸出,set底層是紅黑樹,自動(dòng)幫我們排列好,感興趣的同學(xué)可以去看看set用法和底層操作)。

最終ac代碼如下:

#include<iostream>
#include<string>
#include<set>
using namespace std;
string s1, s2;
int arr[101][101]={0};//動(dòng)態(tài)規(guī)劃表
set <string> lsc_s;
int lsc_max(int m, int n)//求出最大公共子序列的長(zhǎng)度 
{
	for(int i=1;i<=m;i++)
	{
		for(int j=1;j<=n;j++)
		{
			if(s1[i-1]==s2[j-1])arr[i][j]=arr[i-1][j-1]+1;
			else arr[i][j]=max(arr[i-1][j],arr[i][j-1]);
		}
	}
	return arr[m][n];
}
void lsc_print(int i, int j, string str)
{
	while(i>0&&j>0)
	{
		if(s1[i-1]==s2[j-1])
		{
			i--;
			j--;
			str=s1[i]+str;
		}
		else
		{
			if(arr[i-1][j]>arr[i][j-1])i--;
			else if(arr[i-1][j]<arr[i][j-1])j--;
			else 
			{
				lsc_print(i-1,j,str);
				lsc_print(i,j-1,str);
				return;
			}
		}
	}
	if(str.length())lsc_s.insert(str);
}
int main()
{
	cin>>s1>>s2;
	int m=s1.length();
	int n=s2.length();
	int len=lsc_max(m,n);
	string str;
	lsc_print(m, n, str);
	set<string>::iterator it=lsc_s.begin();
	if(lsc_s.empty())
	{
		cout<<"NO"<<endl;
		return 0;
	}
	while(it!=lsc_s.end())
	{
		cout<<*it<<endl;
		it++;
	}
	return 0;
}

如果本篇文章對(duì)你有所幫助的話,記得點(diǎn)贊哦!如果哪里寫得不好的話,也可以評(píng)論,歡迎指正!文章來源地址http://www.zghlxwxcb.cn/news/detail-418204.html

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

本文來自互聯(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)文章

  • 動(dòng)態(tài)規(guī)劃之最長(zhǎng)公共子序列模板

    夏令營(yíng):動(dòng)態(tài)規(guī)劃特訓(xùn) - 【算法模板題】最長(zhǎng)公共子序列 - 藍(lán)橋云課 (lanqiao.cn) 我們來解釋一下狀態(tài)轉(zhuǎn)移方程吧。 dp[i][j]的含義是第i個(gè)和第j個(gè)字符,i與j的下標(biāo)從1開始,代表著原子符串的第一個(gè)字符。那么理所當(dāng)然字符串a(chǎn)的第0個(gè)字符和字符串b的0個(gè)字符的公共長(zhǎng)度為0.如果字

    2024年02月12日
    瀏覽(18)
  • 【動(dòng)態(tài)規(guī)劃】最長(zhǎng)公共子序列Python實(shí)現(xiàn)

    個(gè)人主頁(yè):丷從心 系列專欄:動(dòng)態(tài)規(guī)劃算法 問題描述 給定兩個(gè)序列 X = { ? x 1 , x 2 , ? ? , x m ? } X = set{x_{1} , x_{2} , cdots , x_{m}} X = { x 1 ? , x 2 ? , ? , x m ? } 和 Y = { ? y 1 , y 2 , ? ? , y n ? } Y = set{y_{1} , y_{2} , cdots , y_{n}} Y = { y 1 ? , y 2 ? , ? , y n ? } ,找出 X X X

    2024年02月20日
    瀏覽(29)
  • 動(dòng)態(tài)規(guī)劃-----最長(zhǎng)公共子序列(及其衍生問題)

    動(dòng)態(tài)規(guī)劃-----最長(zhǎng)公共子序列(及其衍生問題)

    目錄 一.最長(zhǎng)公共子序列的基本概念: 解決動(dòng)態(tài)規(guī)劃問題的一般思路(三大步驟): 二.最長(zhǎng)公共子序列題目: 三.字符串的刪除操作: 四.最小 ASCII 刪除和: 首先需要科普一下,最長(zhǎng)公共子序列(longest common sequence)和最長(zhǎng)公共子串(longest common substring)不是一回事兒。什么

    2024年03月26日
    瀏覽(19)
  • 動(dòng)態(tài)規(guī)劃-最長(zhǎng)公共子序列(c語言)

    動(dòng)態(tài)規(guī)劃-最長(zhǎng)公共子序列(c語言)

    實(shí)驗(yàn) 3: 最長(zhǎng)公共子序列 內(nèi)容: 給定兩個(gè)字符串str1和str2,輸出兩個(gè)字符串的最長(zhǎng)公共子序列,如果最長(zhǎng)公共子序列為空,則返回“-1”。目前給出的數(shù)據(jù),僅僅會(huì)存在一個(gè)最長(zhǎng)的公共子序列。 數(shù)據(jù)范圍: 0 ≤|str1|,|str2|≤2000 要求: 空間復(fù)雜度O(n 2 ) 具體思路: step1:

    2024年02月04日
    瀏覽(32)
  • 【動(dòng)態(tài)規(guī)劃】最長(zhǎng)公共子序列——算法設(shè)計(jì)與分析

    【動(dòng)態(tài)規(guī)劃】最長(zhǎng)公共子序列——算法設(shè)計(jì)與分析

    子序列是給定序列中在任意位置去掉任意多個(gè)字符后得到的結(jié)果。例如: 給定序列 X X X : X : A B C B D A B X:ABCBDAB X : A BCB D A B X X X 的子序列: X 1 : A B C B D A B X_1:ABCBDAB X 1 ? : A BCB D A B X 2 : A B C B X_2:ABCB X 2 ? : A BCB X 3 : A C B B X_3:ACBB X 3 ? : A CBB 給定兩個(gè)序列

    2024年02月05日
    瀏覽(27)
  • (Java) 算法——?jiǎng)討B(tài)規(guī)劃 最長(zhǎng)公共子序列 圖解

    (Java) 算法——?jiǎng)討B(tài)規(guī)劃 最長(zhǎng)公共子序列 圖解

    遇到了用動(dòng)態(tài)規(guī)劃來求解最長(zhǎng)公共子序列問題,算法這塊兒比較薄弱,便想著在網(wǎng)上找現(xiàn)成的思路和代碼,也算拾人牙慧,但有一點(diǎn)沒想到,都已經(jīng)22年了,關(guān)于LCS問題網(wǎng)上給出的答案如此一言難盡……,只有零散幾篇對(duì)于 新手 來說比較友好,但也僅僅這樣,好在自己花了點(diǎn)

    2023年04月08日
    瀏覽(21)
  • 動(dòng)態(tài)規(guī)劃應(yīng)用篇:詳解最長(zhǎng)公共子序列問題

    動(dòng)態(tài)規(guī)劃應(yīng)用篇:詳解最長(zhǎng)公共子序列問題

    動(dòng)態(tài)規(guī)劃 是一個(gè)強(qiáng)大的工具,將復(fù)雜問題 分解 為多個(gè)容易解決的子問題,并且會(huì)對(duì)中間結(jié)果進(jìn)行存儲(chǔ)從而避免重復(fù)計(jì)算,然后將它們的解組合起來,形成大問題的解,高效地得出 全局最優(yōu)解 。前面我們已經(jīng)了解了動(dòng)態(tài)規(guī)劃的基礎(chǔ)知識(shí)及一維動(dòng)態(tài)規(guī)劃問題的求解,今天,我

    2024年04月15日
    瀏覽(21)
  • 兩個(gè)數(shù)組的動(dòng)態(tài)規(guī)劃——最長(zhǎng)公共子序列模型

    兩個(gè)數(shù)組的動(dòng)態(tài)規(guī)劃——最長(zhǎng)公共子序列模型

    1.考慮空串,即dp表多出一行一列, 代表某個(gè)字符串為空。 2.考慮最后一個(gè)位置;是否相等; 3.可在字符串最前面加虛擬位置以對(duì)應(yīng)映射關(guān)系; 4.一般橫行是j,列是i。此時(shí)第一行代表第二個(gè)字符串不為空,即第一個(gè)字符串是空的 給你兩個(gè)字符串? s ? 和? t ?,統(tǒng)計(jì)并返回在

    2024年03月10日
    瀏覽(19)
  • leetcode1143. 最長(zhǎng)公共子序列-動(dòng)態(tài)規(guī)劃(java)

    leetcode1143. 最長(zhǎng)公共子序列 來源:力扣(LeetCode) 鏈接:https://leetcode.cn/problems/longest-common-subsequence 給定兩個(gè)字符串 text1 和 text2,返回這兩個(gè)字符串的最長(zhǎng) 公共子序列 的長(zhǎng)度。如果不存在 公共子序列 ,返回 0 。 一個(gè)字符串的 子序列 是指這樣一個(gè)新的字符串: 它是由原字

    2024年01月19日
    瀏覽(27)
  • 【算法(四·三):動(dòng)態(tài)規(guī)劃思想——最長(zhǎng)公共子序列問題】

    【算法(四·三):動(dòng)態(tài)規(guī)劃思想——最長(zhǎng)公共子序列問題】

    最長(zhǎng)公共子序列(Longest Common Subsequence,簡(jiǎn)稱LCS)問題是一種常見的字符串處理問題。它的**目標(biāo)是找到兩個(gè)或多個(gè)字符串中的最長(zhǎng)公共子序列,這個(gè)子序列不需要是連續(xù)的,但字符在原始字符串中的相對(duì)順序必須保持一致。**例如,考慮兩個(gè)字符串\\\"ABCD\\\"和\\\"ACDF\\\",它們的最長(zhǎng)公

    2024年04月13日
    瀏覽(19)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包