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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

最短公共超序列(最短公共父序列)

發布時間:2024/3/13 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 最短公共超序列(最短公共父序列) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

    • 定義
      • 樣例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項的最短公共超序列的位數

  • 當X(Y)至少有一個序列為空時:
    此時最短公共超序列z一定要包含X(Y)全部字符,而求最短公共超序列,于是最短公共超序列就是X(Y)
  • Y為空時:dp(i,0)=i (1<=i<=m)
    X為空時:dp(0,j)=j (1<=j<=n)

  • 當Xm=Yn時
    此時,該字母一定包含在最短公共超序列中,相等就只需要加一個就好啦。(比如x中是a,y中也是a,最短公共超序列中只需要加一個a就行了)
  • dp(m,n)=dp(m-1,n-1)+1

  • 當Xm!=Yn時, 當xm(yn)為最短公共超序列中需要新添加的一個字符時(x出現了一個從來沒出來的字符)
  • 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; }

    總結

    以上是生活随笔為你收集整理的最短公共超序列(最短公共父序列)的全部內容,希望文章能夠幫你解決所遇到的問題。

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