C++動(dòng)態(tài)規(guī)劃實(shí)現(xiàn)查找最長(zhǎng)公共子序列
最長(zhǎng)公共子序列
最長(zhǎng)公共子序列(LCS)是一個(gè)在一個(gè)序列集合中(通常為兩個(gè)序列)用來(lái)查找所有序列中最長(zhǎng)子序列的問(wèn)題。一個(gè)數(shù)列 ,如果分別是兩個(gè)或多個(gè)已知數(shù)列的子序列,且是所有符合此條件序列中最長(zhǎng)的,則稱為已知序列的最長(zhǎng)公共子序列。
動(dòng)態(tài)規(guī)劃:
采用二維數(shù)組flag來(lái)記錄下標(biāo)i和j的走向。數(shù)字"1"表示,斜向下;數(shù)字"2"表示,水平向右;數(shù)字"3"表示,豎直向下
問(wèn)題描述: 設(shè)有字符串a(chǎn)[0…n],b[0…m],下面就是遞推公式。字符串a(chǎn)對(duì)應(yīng)的是二維數(shù)組num的行,字符串b對(duì)應(yīng)的是二維數(shù)組num的列。
代碼實(shí)現(xiàn)
#include<stdio.h> #include<string.h> char a[500],b[500]; char num[501][501]; ///記錄中間結(jié)果的數(shù)組 char flag[501][501]; ///標(biāo)記數(shù)組,用于標(biāo)識(shí)下標(biāo)的走向,構(gòu)造出公共子序列 void LCS(); ///動(dòng)態(tài)規(guī)劃求解 void getLCS(); ///采用倒推方式求最長(zhǎng)公共子序列 int main() { int i; strcpy(a,"ABCBDAB"); strcpy(b,"BDCABA"); memset(num,0,sizeof(num)); memset(flag,0,sizeof(flag)); LCS(); printf("%d\n",num[strlen(a)][strlen(b)]); getLCS(); return 0; } void LCS() { int i,j; for(i=1;i<=strlen(a);i++) { for(j=1;j<=strlen(b);j++) { if(a[i-1]==b[j-1]) ///注意這里的下標(biāo)是i-1與j-1 { num[i][j]=num[i-1][j-1]+1; flag[i][j]=1; ///斜向下標(biāo)記 } else if(num[i][j-1]>num[i-1][j]) { num[i][j]=num[i][j-1]; flag[i][j]=2; ///向右標(biāo)記 } else { num[i][j]=num[i-1][j]; flag[i][j]=3; ///向下標(biāo)記 } } } } void getLCS() { char res[500]; int i=strlen(a); int j=strlen(b); int k=0; ///用于保存結(jié)果的數(shù)組標(biāo)志位 while(i>0 && j>0) { if(flag[i][j]==1) ///如果是斜向下標(biāo)記 { res[k]=a[i-1]; k++; i--; j--; } else if(flag[i][j]==2) ///如果是斜向右標(biāo)記 j--; else if(flag[i][j]==3) ///如果是斜向下標(biāo)記 i--; } for(i=k-1;i>=0;i--) printf("%c",res[i]); }
結(jié)果
時(shí)間復(fù)雜度:
由于只需要填一個(gè)m行n列的二維數(shù)組,其中m代表第一個(gè)字符串長(zhǎng)度,n代表第二個(gè)字符串長(zhǎng)度,所以時(shí)間復(fù)雜度為O(m*n)。
到此這篇關(guān)于C++動(dòng)態(tài)規(guī)劃實(shí)現(xiàn)查找最長(zhǎng)公共子序列的文章就介紹到這了,更多相關(guān)C++最長(zhǎng)公共子序列內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- C++中的動(dòng)態(tài)規(guī)劃子序列問(wèn)題分析探討
- C++動(dòng)態(tài)規(guī)劃計(jì)算最大子數(shù)組
- C++動(dòng)態(tài)規(guī)劃算法實(shí)現(xiàn)矩陣鏈乘法
- C++?動(dòng)態(tài)規(guī)劃算法使用分析
- C++編輯距離(動(dòng)態(tài)規(guī)劃)
- c++動(dòng)態(tài)規(guī)劃經(jīng)典算法
- C++動(dòng)態(tài)規(guī)劃之最長(zhǎng)公子序列實(shí)例
- C++動(dòng)態(tài)規(guī)劃之背包問(wèn)題解決方法
- C++動(dòng)態(tài)規(guī)劃中關(guān)于背包問(wèn)題講解
相關(guān)文章
關(guān)于C++讀入數(shù)字按位取出與進(jìn)制轉(zhuǎn)換問(wèn)題(典型問(wèn)題)
這篇文章主要介紹了關(guān)于C++讀入數(shù)字按位取出與進(jìn)制轉(zhuǎn)換問(wèn)題,是一個(gè)非常典型的問(wèn)題,本文通過(guò)實(shí)例舉例給大家介紹的非常詳細(xì),需要的朋友可以參考下2020-02-02Qt5+QMediaPlayer實(shí)現(xiàn)音樂(lè)播放器的示例代碼
這篇文章主要為大家詳細(xì)介紹了如何利用Qt5和QMediaPlayer實(shí)現(xiàn)簡(jiǎn)易的音樂(lè)播放器,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的可以參考一下2022-12-12C++實(shí)現(xiàn)職工工資管理系統(tǒng)課程設(shè)計(jì)
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)職工工資管理系統(tǒng)課程設(shè)計(jì),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03window調(diào)用api列出當(dāng)前所有進(jìn)程示例
這篇文章主要介紹了window調(diào)用api列出當(dāng)前所有進(jìn)程示例,需要的朋友可以參考下2014-04-04c++實(shí)現(xiàn)對(duì)輸入數(shù)組進(jìn)行快速排序的示例(推薦)
下面小編就為大家?guī)?lái)一篇c++實(shí)現(xiàn)對(duì)輸入數(shù)組進(jìn)行快速排序的示例(推薦)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-06-06