最短公共超序列(最短公共父序列)
文章目錄
- 定義
- 樣例1
- 樣例2
- 遞推公式
- 樣例過程圖解
- c語言代碼
定義
給出兩個字符串 str1 和 str2,返回同時以 str1 和 str2 作為子序列的最短字符串。如果答案不止一個,則可以返回滿足條件的任意一個答案。
(如果從字符串 T 中刪除一些字符(也可能不刪除,并且選出的這些字符可以位于 T 中的 任意位置),可以得到字符串 S,那么 S 就是 T 的子序列)
樣例1
輸入:str1 = “abac”, str2 = “cab”
輸出:“cabac”
解釋:刪去 “cabac” 第一個字母的 “c” 得到 “abac”。
刪去 “cabac” 最后兩個字母 “ac” 得到 “cab”。
樣例2
輸入:str1 = “AABXFGA”, str2 = “ABAAXGF”
輸出:“ABAABXGFGA”
解釋:刪去 “ABAABXGFGA” 加黑字母 得到"AABXFGA"。
刪去 "ABAABXGFGA “加黑字母"ABAAXGF”。
遞推公式
最短公共超序列和最長公共子序列有些相似、
設序列X={x1,x2…xm},Y={y1,y2…yn}
X與Y的最短公共超序列為Z={z1,z2…zk}(z都是x和y序列中的字符)
dp(m,n)表示序列X的前m項和序列Y的前n項的最短公共超序列的位數
此時最短公共超序列z一定要包含X(Y)全部字符,而求最短公共超序列,于是最短公共超序列就是X(Y)
Y為空時:dp(i,0)=i (1<=i<=m)
X為空時:dp(0,j)=j (1<=j<=n)
此時,該字母一定包含在最短公共超序列中,相等就只需要加一個就好啦。(比如x中是a,y中也是a,最短公共超序列中只需要加一個a就行了)
dp(m,n)=dp(m-1,n-1)+1
dp[i][j]=dp[i-1][j]+1
dp[i][j]=dp[i][j-1]+1
則遞推公式為:
樣例過程圖解
str1 = “AABXFGA”,
str2 = “ABAAXGF”
10為最后的結果,藍色代表其中的一種解
c語言代碼
#include <stdio.h> #include <string.h> int max(int a,int b){if(a>b)return a;else return b;} int min(int a,int b){if(a<b)return a;else return b;} int dp[105][105],len1,len2,cou=0; char a[105],b[105],c[105]; //a,b用來存放輸入的兩個字符串,c存放最短公共超序列的一種解 int main() { int i,j;scanf("%s",&a);scanf("%s",&b);len1=strlen(a);len2=strlen(b);for(i=strlen(a);i>0;i--) //為了方便dp數組的操作,我將字符往后移動一位 a[i]=a[i-1];for(i=strlen(b);i>0;i--)b[i]=b[i-1];a[0]='0'; //隨便給的值 b[0]='1';for(i=0;i<=max(len1,len2);i++) //當某個字符串為空時,賦初值 dp[i][0]=dp[0][i]=i;for(i=1;i<=len1;i++){for(j=1;j<=len2;j++){if(a[i]==b[j])dp[i][j]=dp[i-1][j-1]+1; //根據遞推公式求dp() else dp[i][j]=min(dp[i-1][j],dp[i][j-1])+1;}}i=len1;j=len2;while(i>0&&j>0) //根據比較最后的值是怎么來的,計算出最短超序列的一種解 {if(dp[i][j]==dp[i-1][j-1]+1&&a[i]==b[j]) //相等時 {c[cou]=a[i];cou++;i--;j--;}else if(dp[i][j]==dp[i-1][j]+1&&a[i]!=b[j])//來自a {c[cou]=a[i];cou++;i--;}else if(dp[i][j]==dp[i][j-1]+1&&a[i]!=b[j])//來自b {c[cou]=b[j];cou++; j--;} }while(i>0) //輸入的字符串大小不等,或者在a,b中選取的個數不相等時,若第0行或者第0列沒有選完時 {c[cou]=a[i];i--;cou++;}while(j>0){c[cou]=b[j];j--;cou++;}for(i=strlen(c)-1;i>=0;i--) //輸出其中一個最短超序列 printf("%c",c[i]);printf("\n");printf("\n%d",dp[len1][len2]);return 0; }總結
以上是生活随笔為你收集整理的最短公共超序列(最短公共父序列)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: UART串口传图LCD显示----图像处
- 下一篇: EVE-NG模拟器教程(四)——常用镜像