最长公共子序列(C语言)
生活随笔
收集整理的這篇文章主要介紹了
最长公共子序列(C语言)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
任務描述
本關任務:編寫一個求最長公共子序列的程序。
相關知識
兩個序列A[m]=(a1?,...,am?),B[n]=(b1?,b2?,...,bn?),它的公共子序列是C[k]=(c1?,...,ck?),其中ci?來自于A和B,并且C中的順序不違反A和B中的順序。即如果ci?和ci+1?是A中的as?,at?,則s<t. 我們要得到長度最大的C。
例如 A[]={1,2,3,4,5},B[]={2,5,7},則C={2,5}
請你寫一個函數 void LCS(int A[], int m, int B[], int n, int C[], int *k)
其中 A和B是輸入的序列, m和n是長度。 后面兩個參數是函數傳回給測試程序的,其中C是你求出的最長公共子序列,而k是其長度。
測試說明
平臺會對你編寫的代碼進行測試:
測試輸入:A[]={1,2,3,4,5},m=5, B[]={2,5,7},n=3;
預期輸出:則C={2,5},k=2
解析:
先用動態規劃制作dp數組,第一行第一列都置為0,當值相同時,dp值等于左上角的值加一,不同時,等于上面的值和左邊的值中較大的值。制作完dp數組后,dp[m][n]即為我們需要的最長公共子序列的值。然后從這個值往回查詢,來找出最長公共子序列中有哪些值。
#include<stdio.h> #define MAXX 100 int check(int A[],int m, int B[], int n){int ib=0;for (int i=0;i<m;i++){while(ib<n && A[i] != B[ib]) ib++;if (ib>=n) return -1; }return 1; } void LCS(int A[], int m, int B[], int n, int C[], int *k){ # 查詢函數int dp[m+1][n+1]; # dp數組for(int i=0;i<m+1;i++) # 初始化第一列dp[i][0] = 0;for(int i=0;i<n+1;i++) # 初始化第一行dp[0][i] = 0;int h = 0;for(int i=1;i<m+1;i++){ # 構建dp數組for(int j=1;j<n+1;j++){if(A[i-1] == B[j-1]) # 相等時{dp[i][j] = dp[i-1][j-1] + 1;}else # 不等時,可以用max()函數代替{if(dp[i][j-1] > dp[i-1][j])dp[i][j] = dp[i][j-1];elsedp[i][j] = dp[i-1][j];}}}*k = dp[m][n]; # 最長公共子序列的長度int flag = *k;while(flag>-1&&m>-1&&n>-1) # 倒推回去{if(dp[m][n] == dp[m-1][n-1] + 1) # 相等的情況{C[flag-1] = A[m-1];m--;n--;flag--;}else # 不等的情況{if(dp[m][n] == dp[m-1][n]){m = m-1;}else if(dp[m][n] == dp[m][n-1]){n = n-1;}}} }int main(){ int m,n,k; # 這個k沒啥用,題目給的 int A[MAXX],B[MAXX],C[MAXX];scanf("%d %d",&m,&n);for(int i=0;i<m;i++)scanf("%d",&A[i]);for(int i=0;i<n;i++)scanf("%d",&B[i]); int K;LCS(A,m,B,n,C,&K);if (check(C,K,A,m)==1 && check(C,K,B,n)==1 ) printf("%d",K);return 1; }# 好久沒寫c了,代碼可能有點繁瑣。
總結
以上是生活随笔為你收集整理的最长公共子序列(C语言)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网络按通信方式分类可分为哪些(三种通信方
- 下一篇: 0-1背包问题(C语言)