最长公共子串/子序列
来源:互联网 发布:霍先生家的安之知 编辑:程序博客网 时间:2024/04/27 15:48
最长公共子串:找两个字符串的最长公共子串,要求在原字符串中是连续的
最长公共子序列:不要求连续
最长公共子串思路:
声明一个二维数组dp[][]来存放相对应的最长公共子串数
arr1[m]=arr2[n]时,dp[m+1][n+1]=1+dp[m][n] 即当子序列中第 m+1 元素与目标序列中第 n+1 元素相同时,子序列前 m+1 个元素与目标序列前 n+1 个元素的最长公共子串数为子序列前 m 个元素与目标序列前 n 个元素的最长公共子串数 + 1;
arr1[m] != arr2[n]时,dp[m+1][n+1]=0;即当子序列中第 m+1 元素与目标序列中第 n+1 元素不相同时,子序列前 m+1 个元素与目标序列前 n+1 个元素的最长公共子串长为0 ;第二步:找出最大值,依次输出其左上角
#include<stdio.h>int weight[101];//子串权值char substr[101];//子串字母char sbustrs[100][100];//int maxlcs=0;//LCS大小int a=0;char arr1[]="bab";char arr2[]="caba";int dp[101][101]={0};//dp[i][j]存放字串前i-1,目标串前j-1个元素的LCS,初始全为0int LCS(char *arr1,int size1 ,char *arr2,int size2 )//求出dp[][];{for(int i=0 ;i < size1; i++ )//依次增加子序列长度{for(int j=0 ;j< size2; j++)//依次增加目标序列长度{if(arr1[i]==arr2[j]){dp[j+1][i+1]=dp[j][i]+1;//当前匹配相同,对应LCS等于前一LCS+1if(maxlcs<dp[j+1][i+1])maxlcs= dp[j+1][i+1];//找到LCS的最大值}else dp[j+1][i+1]=0;//当前匹配不同,对应LCS等于左侧和上侧LCS中的较大值}}return 0;}int Find ( int n ,int m ,int nextmax )//找出所有匹配点,记录相应字符和权值{ int k, j;if (nextmax==0){ printf("\n");return 0;}for(k=m+n ; k>0 ;k--){for( j=n ; j>0 && (k-j)<(m+1) ; j--){if(dp[k-j][j]==nextmax){ printf("%d %d %d",k-j,j,nextmax);printf("%c ",arr1[j-1]);if (nextmax==0) printf("\n");Find(j-1,k-j-1,nextmax-1);//递归查找下一层级}}}return 0;}int main(){LCS(arr1,3,arr2,4);Find(3,4,maxlcs);return 0;}
最长公共子序列思路:
第一步:声明一个二维数组dp[][]来存放相对应的最长公共子序列数
arr1[m]=arr2[n]时,dp[m+1][n+1]=1+dp[m][n] 即当子序列中第 m+1 元素与目标序列中第 n+1 元素相同时,子序列前 m+1 个元素与目标序列前 n+1 个元素的最长公共子序列数为子序列前 m 个元素与目标序列前 n 个元素的最长公共子序列数 + 1;
arr1[m] != arr2[n]时,dp[m+1][n+1]=max{dp[m][n+1],dp[m+1][n]} 即当子序列中第 m+1 元素与目标序列中第 n+1 元素不相同时,子序列前 m+1 个元素与目标序列前 n+1 个元素的最长公共子序列数为子序列前 m 个元素与目标序列前 n+1 个元素的最长公共子序列数 和 子序列前 m+1 个元素与目标序列前 n 个元素的最长公共子序列数中的较大值 ;
第二步:递归找出每一个匹配点对应的子序列,递归输出
1 #include<stdio.h> 2 char substr[101];//子串字母 3 int maxlcs=0;//LCS大小 4 char arr1[]="DADFDAB"; 5 char arr2[]="ABDEFAFCD"; 6 int dp[101][101]={0};//dp[i][j]存放字串前i-1,目标串前j-1个元素的LCS,初始全为0 7 int LCS(char *arr1,int size1 ,char *arr2,int size2 )//求出dp[][]; 8 { 9 for(int i=0 ;i < size1; i++ )//依次增加子序列长度 10 { 11 for(int j=0 ;j< size2; j++)//依次增加目标序列长度 12 { 13 if(arr1[i]==arr2[j]) dp[j+1][i+1]=dp[j][i]+1;//当前匹配相同,对应LCS等于前一LCS+1 14 else dp[j+1][i+1]=(dp[j+1][i]>dp[j][i+1]?dp[j+1][i]:dp[j][i+1]);//当前匹配不同,对应LCS等于左侧和上侧LCS中的较大值 15 } 16 } 17 maxlcs= dp[size2][size1];//找到LCS的最大值 18 return 0; 19 } 20 int Find ( int n ,int m ,int nextmax )//找出所有匹配点,记录相应字符和权值 21 { 22 int k, j; 23 if (nextmax==0){ printf("%s \n",substr);return 0;}//当找到首个元素后输出记录 24 for(k=m+n ; k>0 ;k--) 25 { 26 for( j=n ; j>0 && (k-j)<(m+1) ; j--) 27 { 28 if((dp[k-j][j]==nextmax) && (arr1[j-1]==arr2[k-j-1]))//权值为当前最大,且对应字母匹配则记录 29 { 30 substr[maxlcs-nextmax]=arr1[j-1];//将记录存入数组与递归层数相对应位置,新分支覆盖原有分支,保留共用部分 31 Find(j-1,k-j-1,nextmax-1);//递归查找下一层级 32 } 33 } 34 } 35 return 0; 36 } 37 int main() 38 { 39 LCS(arr1,7,arr2,9); 40 Find(7,9,maxlcs); 41 return 0; 42 }
- 最长公共子串、最长公共子序列、最长递增子序列、最长回文子串
- 求解最大子序列、最长递增子序列、最长公共子串、最长公共子序列
- 最长公共子序列、上升子序列、最长上升子序列、最长公共子串
- 最大子序列和、最长递增子序列、最长公共子串、最长公共子序列
- 最大子序列和、最长递增子序列、最长公共子串、最长公共子序列
- 最大子序列、最长递增子序列、最长公共子串、最长公共子序列、
- 最大子序列最长递增子序列最长公共子串最长公共子序列
- 最长公共子序列与子串
- 最长公共子串/子序列
- 最长公共子串和子序列
- 最长公共子序列、子串
- 整理:最长公共子串及最长公共子序列
- 最长公共子串和最长公共子序列
- 最长公共子序列和最长公共子串
- 最长公共子序列&最长公共子串
- 最长公共子序列 与 最长公共子串
- 最长公共子串 & 最长公共子序列
- 最长公共子序列和最长公共子串
- 从EXE文件中提取音乐、图片等资源
- MeasureSpec介绍及使用详解
- css3 roatae锯齿
- Android 官方推荐 : DialogFragment 创建对话框
- WordPress加速缓存插件WP Super cache安装方法及使用技巧
- 最长公共子串/子序列
- 请描述五模型中数据传输的基本过程
- 王立平--Gallery:实现图片的左右滑动
- 黑马程序员——OC中的点语法及属性作用域
- MOOC开启教育在线互动模式,知识全球化进程快速
- python3 基础总结及模块安装
- Android中颜色的表示
- 第九周项目三信号图(c图)
- web的自动化发布