LCS小结(O(∩_∩)O~吽吽)

LCS!~如果你在百度上搜这个的话会出来”英雄联盟冠军联赛”,orz。。但是今天要讲的LCS是最长公共子序列 ,"Longest Common Subsequence "not"League of Legends Championship Series "小盆友们又要涨姿势了~

最长公共子序列也称作最长公共子串(不要求连续),打个比方说,A君有一个字符串:qazwbx,B君也有一个字符串:azwsxq,那么我们可以说a君和B君的最长公共子序列为:azwx,长度为4,这样看来好像挺简单的,但是如果字符串很长或者比较的字符串个数很多,要求出公共的而且是最长的就能比较困难了,为了方便小盆友们方便的求得 最长公共子序列,我们引入高大上的DP君!

这里我们采用的是矩阵实现,也就是二维数组。

第一步:先计算最长公共子序列的长度。

第二步:根据长度,然后通过回溯求出最长公共子序列。

 先来实现第一步吧:

设一个C[i][j]: 保存Xi与Yj的LCS的长度。

设X = { x1~xm },Y = { y1~yn }及它们的最长子序列Z = { z1~zk }则:

1、若 xm = yn , 则 zk = xm = yn,且Z[k-1] 是 X[m-1] 和 Y[n-1] 的最长公共子序列

2、若 xm != yn ,且 zk != xm , 则 Z 是 X[m-1] 和 Y 的最长公共子序列

3、若 xm != yn , 且 zk != yn , 则 Z 是 Y[n-1] 和 X 的最长公共子序列

子问题的递归结构:

当 i = 0 , j = 0 时 , c[i][j] = 0

当 i , j > 0 ; xi = yi 时 , c[i][j] = c[i-1][j-1] + 1

当 i , j > 0 ; xi != yi 时 , c[i][j] = max { c[i][j-1] , c[i-1][j] }

下面的代码是求两个字符串的最长公共子串:

 1 int LCS(int n,int m)//n,m分别为两个字符串的长度
 2 {
 3     int i,j;
 4     int len=max(n,m);
 5     for(i=0;i<=len;i++)
 6     {
 7         dp[i][0]=0;
 8         dp[0][i]=0;
 9     }
10     for(i=1;i<=n;i++)
11     {
12         for(j=1;j<=m;j++)
13         {
14             if(a[i-1]==b[j-1])
15             {
16                 dp[i][j]=dp[i-1][j-1]+1;
17             }
18             else
19             {
20                 dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
21             }
22         }
23     }
24     return dp[n][m];
25 }

第二步:通过回溯求出最长公共子序列

如图:

下面给出逆序输出最长公共子串的代码:

 1 int i=n-1,j=m-1,count=k;
 2         while(count!=0)
 3         {
 4             if(a[i]==b[j])
 5             {
 6                 cout<<a[i];
 7                 i--;
 8                 j--;
 9                 count--;
10             }
11             else if(dp[i][j-1]>dp[i-1][j])
12             {
13                 j--;
14             }
15             else
16             {
17                 i--;
18             }
19         }cout<<endl;

从最后开始,碰到一样的输出,不一样的,往更大的方向跑。其实就是前面生成dp的逆过程。

LCS粗略的讲完了,还有很多不足,希望大家多多补充~

LCS小结(O(∩_∩)O~吽吽)

时间: 2024-10-02 22:33:58

LCS小结(O(∩_∩)O~吽吽)的相关文章

-----[DP] LCS小结

额..失误.. LCS是Longest Common Subsequence的缩写,即最长公共子序列.一个序列,如果是两个或多个已知序列的子序列,且是所有子序列中最长的,则为最长公共子序列. DP.O(n^2)解法: #include <iostream> #include <cstdio> #include <cstring> using namespace std; #define max(a,b) ((a)>(b)?(a):(b)) #define N 10

LIS小结(O(∩_∩)O~哄哄)

~\(≧▽≦)/~啦啦啦,昨天说的是LCS,今天我们要学习的是LIS,什么是LIS呢?  LIS: 最长有序子序列(递增/递减/非递增/非递减)这么说还是有些模糊,举个例子: 在一个无序的序列a1,a2,.....,am里,找到一个最长的序列,满足ai<=aj...<=ak; 且i<j<k; 例如该无序子序列为a[1]=1,a[2]=4,a[3]=5,a[4]=2;则最长序列为1,4,5. 小盆友们是不是明白了什么是最长有序子序列了呢?下面我们说说怎么求最长有序子序列: 先来说说经

(萌O(∩_∩)O)哈希知识点小结

噶呜~先来了解一下什么是哈希吧? 当我们要在一堆东西中找到想要的那一个东西,我们常常通过比较来找,理想的情况是不经过任何比较,一次就能找到,怎么才能做到这样呢?那就在记录的储存位置和他的关键字之间建立一个确定的对应关系,我们称这种对应关系为哈希函数~小盆友们应该对哈希有了一个初步的印象了吧?其实,哈希函数就是一个映像,设定很灵活,只要使任何关键字由这个哈希函数所得的哈希函数值都落在一定范围内即可.当然,不同的关键字可能得到同一哈希地址,这就出现了所谓的冲突,至于怎么解决这种冲突,稍后就会了解到.

OO_JML专题_小结

第一部分:JML小结 一.入门关键字小结 1.引导词: requires :接下来部分的入口要求 assignable :在该程序中可修改的变量 ensures :后面是对该函数运行结束后的要求 also  exception_behavior :接下来是出现异常的处理部分 signals : 对应抛出的异常 2.转义词: \nothing :(一般用在assignable中,表示都不可修改) \everything :(一般用在assignable中,表示都可修改) \old :该函数修改前某

第七章小结_查找

查找 一些定义 召回率和准确率 因为PTA上的题目会涉及,所以在这里提一下 参考:精度评定中的准确率(Precision)和召回率(Recall),怎样量化评价搜索引擎的结果质量 当进行查找的时候,样本会被分成两类,在这里举例:苹果和非苹果 那么进行检索的时候,就会出现四种情况: 苹果被认为是苹果 不是苹果被认为是苹果 苹果被认为是非苹果 不是苹果被认为是非苹果 召回率(Recall) = 系统检索到的相关文件 / 系统所有相关的文件总数 准确率(Precision) = 系统检索到的相关文件

[六字真言]6.吽.SpringMVC中上传大小异常填坑

最近在讲课的时候,遇到了关于上传文件过大的时候浏览器无法响应的问题,配置了捕获异常,有的学生浏览器好使,有的学生浏览器不好用!莫名其妙! MaxUploadSizeExceededException进入了无限的死循环,╮(╯▽╰)╭ 悲催! 为什么呢? 配置上传信息 在springmvc的核心配置文件配置如下信息 <!-- 5.配置上传 --> <bean id="multipartResolver" class="org.springframework.w

嗡嘛呢叭咪吽

二分查找: 一般而言,对于包含n个元素的列表,用二分查找最多需要log2 n(以2为底,n的对数)步,而简单查找最多需要n步. 仅当列表是有序的时候,二分查找才管用. 函数 binary_search 接受一个有序数组和一个元素.如果指定的元素包含在数组中,这个函数将返回其位置. low = 0  high = len(list) - 1  mid = (low + high) / 2 guess = list[mid] 如果猜的数字小了,就相应地修改 low .if guess < item:

第四章_串、数组和广义表_学习小结

串.数组和广义表 广义表被鸽了,暂时就不提它,总结一下串和数组的心得. 串 串本身不难,好比字符数组,都是我们所熟悉的.难得是与其相关的算法,例如KMP算法. 对于KMP算法,难点在于next数组的取得与使用. 点击跳转:基于KMP算法的字符匹配问题 以上是个人的一些见解,当然是参考别人的博客之后的.... 数组 至于数组,这里主要研究二维数组的应用,比如用三元组表压缩存储. 由于书里连ADT都没有,只能自己摸索着定义了....(还不是为了PTA的题目QAQ)所以就稍微详细说一下 例:用三元组表

date命令小结

在写linux shell脚本时,date是经常要用到的一个命令,这篇文章就此做个小结,以防自己用到时到处找 1.最基本的,显示当前的具体时期:直接敲入 date即可,如下, [email protected]:~/scripts$ date 2015年 01月 03日 星期六 21:46:49 CST 2.显示某个文件上次修改的时间:date -r file [email protected]:~/scripts$ date -r save.sh 2015年 01月 02日 星期五 23:29