1 using System; 2 namespace ConsoleApplication2 3 { 4 public class Program 5 { 6 static int[,] martix; 7 8 static string str1 = "cnblogs"; 9 static string str2 = "belong"; 10 11 static void Main(string[] args) 12 { 13 martix = new int[str1.Length + 1, str2.Length + 1]; 14 15 LCS(str1, str2); 16 17 //只要拿出矩阵最后一个位置的数字即可 18 Console.WriteLine("当前最大公共子序列的长度为:{0}", martix[str1.Length, str2.Length]); 19 20 Console.Read(); 21 } 22 23 static void LCS(string str1, string str2) 24 { 25 //初始化边界,过滤掉0的情况 26 for (int i = 0; i <= str1.Length; i++) 27 martix[i, 0] = 0; 28 29 for (int j = 0; j <= str2.Length; j++) 30 martix[0, j] = 0; 31 32 //填充矩阵 33 for (int i = 1; i <= str1.Length; i++) 34 { 35 for (int j = 1; j <= str2.Length; j++) 36 { 37 //相等的情况 38 if (str1[i - 1] == str2[j - 1]) 39 { 40 martix[i, j] = martix[i - 1, j - 1] + 1; 41 } 42 else 43 { 44 //比较“左边”和“上边“,根据其max来填充 45 if (martix[i - 1, j] >= martix[i, j - 1]) 46 martix[i, j] = martix[i - 1, j]; 47 else 48 martix[i, j] = martix[i, j - 1]; 49 } 50 } 51 } 52 } 53 } 54 }
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 int MAX(int a, int b) 6 { 7 return a>b?a:b; 8 } 9 int f(char* x, char* y) 10 { 11 if(strlen(x)==0) return 0; 12 if(strlen(y)==0) return 0; 13 if(*x == *y) return f(x+1,y+1)+1; 14 return MAX(f(x,y+1),f(x+1,y)); 15 } 16 int main() 17 { 18 printf("%d\n", f("ac","abcd")); //2 19 printf("%d\n", f("acebbcde1133","xya33bc11de")); //5 20 return 0; 21 }
概念:
举个例子,cnblogs这个字符串中子序列有多少个呢?很显然有27个,比如其中的cb,cgs等等都是其子序列,我们可以看出
子序列不见得一定是连续的,连续的那是子串。
分析:
既然是经典的题目肯定是有优化空间的,并且解题方式是有固定流程的,这里我们采用的是矩阵实现,也就是二维数组。
第一步:先计算最长公共子序列的长度。
第二步:根据长度,然后通过回溯求出最长公共子序列。
现有两个序列X={x1,x2,x3,...xi},Y={y1,y2,y3,....,yi},
设一个C[i,j]: 保存Xi与Yj的LCS的长度。
动态规划的一个重要性质特点就是解决“子问题重叠”的场景,可以有效的避免重复计算,根据上面的公式其实可以发现C[i,j]一直保存着当前(Xi,Yi)的最大子序列长度
时间: 2024-10-14 11:40:40