当前位置: 首页 > 编程日记 > 正文

最长公共子序列(LCS)问题 Longest Common Subsequence 与最长公告字串 longest common substr...

问题描述:字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列。令给定的字符序列X=“x0,x1,…,xm-1”,序列Y=“y0,y1,…,yk-1”是X的子序列,存在X的一个严格递增下标序列<i0,i1,…,ik-1>,使得对所有的j=0,1,…,k-1,有xij=yj。例如,X=“ABCBDAB”,Y=“BCDB”是X的一个子序列。

考虑最长公共子序列问题如何分解成子问题,设A=“a0,a1,…,am-1”,B=“b0,b1,…,bm-1”,并Z=“z0,z1,…,zk-1”为它们的最长公共子序列。不难证明有以下性质:

(1) 如果am-1=bn-1,则zk-1=am-1=bn-1,且“z0,z1,…,zk-2”是“a0,a1,…,am-2”和“b0,b1,…,bn-2”的一个最长公共子序列;

(2) 如果am-1!=bn-1,则若zk-1!=am-1,蕴涵“z0,z1,…,zk-1”是“a0,a1,…,am-2”和“b0,b1,…,bn-1”的一个最长公共子序列;

(3) 如果am-1!=bn-1,则若zk-1!=bn-1,蕴涵“z0,z1,…,zk-1”是“a0,a1,…,am-1”和“b0,b1,…,bn-2”的一个最长公共子序列。

这样,在找A和B的公共子序列时,如有am-1=bn-1,则进一步解决一个子问题,找“a0,a1,…,am-2”和“b0,b1,…,bm-2”的一个最长公共子序列;如果am-1!=bn-1,则要解决两个子问题,找出“a0,a1,…,am-2”和“b0,b1,…,bn-1”的一个最长公共子序列和找出“a0,a1,…,am-1”和“b0,b1,…,bn-2”的一个最长公共子序列,再取两者中较长者作为A和B的最长公共子序列。

求解:

引进一个二维数组c[][],用c[i][j]记录X[i]与Y[j] 的LCS 的长度,b[i][j]记录c[i][j]是通过哪一个子问题的值求得的,以决定搜索的方向。
我们是自底向上进行递推计算,那么在计算c[i,j]之前,c[i-1][j-1],c[i-1][j]与c[i][j-1]均已计算出来。此时我们根据X[i] = Y[j]还是X[i] != Y[j],就可以计算出c[i][j]。

问题的递归式写成:

recursive formula

回溯输出最长公共子序列过程:

flow

算法分析:
由于每次调用至少向上或向左(或向上向左同时)移动一步,故最多调用(m + n)次就会遇到i = 0或j = 0的情况,此时开始返回。返回时与递归调用时方向相反,步数相同,故算法时间复杂度为Θ(m + n)。

http://blog.csdn.net/yysdsyl/article/details/4226630

一切没有code的分析都是耍流氓。。。 上code

void printLCS(string str1, string str2, vector<vector<int> >flag, int idx1, int idx2)
{if(idx1 == 0 || idx2 == 0 ) return;if(flag[idx1][idx2] == 1){   printLCS(str1, str2,flag, idx1-1, idx2-1);cout << idx1 <<"\t"<< idx2 <<"\t";cout << str1[idx1-1] <<"\t"<<endl;}   else if(flag[idx1][idx2] == 2)printLCS(str1, str2,flag, idx1, idx2-1);else if(flag[idx1][idx2] == 3)printLCS(str1, str2,flag, idx1-1, idx2);
}int lcs(string str1, string str2)
{const size_t len1 = str1.size();const size_t len2 = str2.size();if(len1 == 0 || len2 == 0)return 0;int f[len1 + 1][len2 + 1];vector<vector<int> >flag;vector<int> tmp;tmp.resize(len2+1);for(size_t i = 0; i<= len1; i++)flag.push_back(tmp);//memset(flag,0,sizeof(flag)); // 1: leftup; 2: left; 3: upfor(size_t i = 0; i <= len1; i++){f[i][0] = 0;}for(size_t i = 0; i <= len2; i++){f[0][i] = 0;}for(size_t i = 1; i <= len1; i++){for(size_t j = 1; j <= len2; j++){if(str1[i-1] == str2[j-1]){f[i][j] = f[i-1][j-1] + 1;flag[i][j] = 1;}else{f[i][j] = max(f[i][j-1], f[i-1][j]);if(f[i][j-1] > f[i-1][j])flag[i][j] = 2;elseflag[i][j] = 3;}}}
#if 0for(size_t i = 1; i <= len1; i++){for(size_t j = 1; j <= len2; j++){//cout << "f["<<j<<"][" <<i<<"]" << f[j][i] <<"\n";cout << f[i][j] <<"\t";}cout << endl;}cout << endl;for(size_t i = 1; i <= len1; i++){for(size_t j = 1; j <= len2; j++){//cout << "f["<<j<<"][" <<i<<"]" << f[j][i] <<"\n";cout << flag[i][j] <<"\t";}cout << endl;}
#endifprintLCS(str1, str2, flag, len1, len2);return f[len1][len2];}

最长公共字串:

找两个字符串的最长公共子串,这个子串要求在原字符串中是连续的。其实这又是一个序贯决策问题,可以用动态规划来求解。我们采用一个二维矩阵来记录中间的结果。这个二维矩阵怎么构造呢?直接举个例子吧:"bab"和"caba"(当然我们现在一眼就可以看出来最长公共子串是"ba"或"ab")

b  a  b

c  0  0  0

a  0  1  0

b  1  0  1

a  0  1  0

我们看矩阵的斜对角线最长的那个就能找出最长公共子串。

不过在二维矩阵上找最长的由1组成的斜对角线也是件麻烦费时的事,下面改进:当要在矩阵是填1时让它等于其左上角元素加1。

b  a  b

c  0  0  0

a  0  1  0

b  1  0  2

a  0  2  0

这样矩阵中的最大元素就是 最长公共子串的长度。

在构造这个二维矩阵的过程中由于得出矩阵的某一行后其上一行就没用了,所以实际上在程序中可以用一维数组来代替这个矩阵。

与Subsequence问题不同的是,Substring问题不光要求下标序列是递增的,还要求每次

递增的增量为1, 即两个下标序列为:

<i, i+1, i+2, ..., i+k-1> 和 <j, j+1, j+2, ..., j+k-1>

类比Subquence问题的动态规划解法,Substring也可以用动态规划解决,令

c[i][j]表示Xi和Yi的最大Substring的长度,比如

X = <y, e, d, f>

Y = <y, e, k, f>

c[1][1] = 1

c[2][2] = 2

c[3][3] = 0

c[4][4] = 1

 动态转移方程为:

   如果xi == yj, 则 c[i][j] = c[i-1][j-1]+1

   如果xi ! = yj,  那么c[i][j] = 0

最后求Longest Common Substring的长度等于

max{  c[i][j],  1<=i<=n, 1<=j<=m}

完整的代码如下:

/** 
找出两个字符串的最长公共连续子串的长度
** author :liuzhiwei  
** data   :2011-08-16
**/ 
#include "stdio.h"
#include "string.h"
#include "stdlib.h"int longest_common_substring(char *str1, char *str2)
{int i,j,k,len1,len2,max,x,y;len1 = strlen(str1);len2 = strlen(str2);int **c = new int*[len1+1];for(i = 0; i < len1+1; i++)c[i] = new int[len2+1];for(i = 0; i < len1+1; i++)c[i][0]=0;        //第0列都初始化为0for(j = 0; j < len2+1; j++)c[0][j]=0;        //第0行都初始化为0 max = -1;for(i = 1 ; i < len1+1 ; i++){for(j = 1; j < len2+1; j++){if(str1[i-1]==str2[j-1])     //只需要跟左上方的c[i-1][j-1]比较就可以了c[i][j]=c[i-1][j-1]+1;else                         //不连续的时候还要跟左边的c[i][j-1]、上边的c[i-1][j]值比较,这里不需要c[i][j]=0;if(c[i][j]>max){max=c[i][j];x=i;y=j;}}}//输出公共子串char s[1000];k=max;i=x-1,j=y-1;s[k--]='\0';while(i>=0 && j>=0){if(str1[i]==str2[j]){s[k--]=str1[i];i--;j--;}else       //只要有一个不相等,就说明相等的公共字符断了,不连续了break;}printf("最长公共子串为:");puts(s);for(i = 0; i < len1+1; i++)         //释放动态申请的二维数组
        delete[] c[i];delete[] c;return max;
}
int main(void)
{char str1[1000],str2[1000];printf("请输入第一个字符串:");gets(str1);printf("请输入第二个字符串:");gets(str2);int len = longest_common_substring(str1, str2);printf("最长公共连续子串的长度为:%d\n",len);system("pause");return 0;
}

转载于:https://www.cnblogs.com/diegodu/p/4248242.html

相关文章:

逆战服务器在哪个文件夹,逆战的背景音乐文件夹放在哪?别说在服务器上面!...

满意答案Dim185629442017.01.11采纳率&#xff1a;58% 等级&#xff1a;13已帮助&#xff1a;7224人你右键逆战图标&#xff0c;有个打开文件位置&#xff0c;点开&#xff0c;找就可以了。。 追问&#xff1a; 如果我把我喜欢的音乐文件放进去&#xff0c;我喜欢的音乐会成…

ruby调用java代码

为什么80%的码农都做不了架构师&#xff1f;>>> ruby使用rjb调用java代码 require rjb#加载jar包 Rjb::load(classpath /home/deployer/DmCodec.jar, jvmargs[]) #new一个对象 DmCodec Rjb::import(com.zapya.DmCodec).new #调用实例方法 tmp DmCodec.encodeB6…

VMware虚拟机安装黑苹果MacOS Mojave系统详细教程

更多资源请百度搜索&#xff1a;前端资源网 欢迎关注我的博客&#xff1a;www.w3h5.com 最近遇到一个H5页面的 iPhone X 刘海兼容问题。查到一个 XCode 编辑器&#xff0c;可以模拟 iPhone X 环境运行。 然后发现&#xff0c;XCode 是专门为苹果的 MacOS 系统设计的一款开发工具…

LSM 优化系列(四) -- Rocksdb和Lethe 对Delete问题的优化

文章目录前言1. 问题背景2. 问题复现3. Rocksdb 的 Delete-Aware 优化3.1 可配置的 Delete-Aware调度3.2 Compaction 逻辑对 delete key的优化4. Lethe: A Tunable Delete-Aware LSM Engine . SIGMOD20前言 本文介绍过程中涉及到的源代码是基于rocksdb 6.4.6 版本的。 同时需…

CodeForces Round #287 Div.2

A. Amr and Music (贪心) 水题&#xff0c;没能秒切&#xff0c;略尴尬。 1 #include <cstdio>2 #include <algorithm>3 using namespace std;4 5 const int maxn 100 10;6 int a[maxn], r[maxn], ans[maxn];7 8 int cmp(int i, int j) { return a[i] < a[j]; …

什么叫安装文件索引服务器,搜出精彩 玩转Windows 2008系统心得

【IT168 专稿】不少朋友已经在不经意间与Windows Server 2008系统进行了亲密接触&#xff0c;在一段时间的接触之后&#xff0c;不知大家对该系统的文件搜索功能会有什么样的体会&#xff1f;其实&#xff0c;Windows Server 2008系统的文件搜索功能与以往相比有了很大进步&…

取eclipse console 打印字符串,判断日志是否有异常

2019独角兽企业重金招聘Python工程师标准>>> 1. 取得当前输入的console /*** 取得控制台的字符串的Docment* param processConsoleName 控制台名称&#xff0c;如在java application 中定义的名字为test ,则这个地方的输入为test即可* return null*/public stati…

PAT乙级1028

1028 人口普查 &#xff08;20 分)某城镇进行人口普查&#xff0c;得到了全体居民的生日。现请你写个程序&#xff0c;找出镇上最年长和最年轻的人。 这里确保每个输入的日期都是合法的&#xff0c;但不一定是合理的——假设已知镇上没有超过 200 岁的老人&#xff0c;而今天是…

Go 分布式学习利器(12)-- Go语言的扩展和复用

Go语言无法天然支持继承&#xff0c;但是又想要实现面向对象的特性。 即父类对象 使用子类对象初始化&#xff0c;那么该父类对象调用的函数就是子类实现的函数 &#xff0c;从而满足LSP&#xff08;子类交换原则&#xff09;。 案例一&#xff1a; Go语言 支持扩展父类的功能…

displaytag 导出

只使用displaytag的导出功能&#xff0c;表单展示用jqgrid实现。只需要后台修改一部分代码&#xff0c;其他的表单都能使用这个功能导出。导出四种文件格式&#xff1a;csv&#xff0c;excel&#xff0c;xml&#xff0c;pdf。 思路&#xff1a;在过滤器中处理&#xff0c;过滤器…

两个下拉框相关联ajax,触发第二个下拉框以显示基于从第一个下拉框中选择的值的值ajax...

我有两个引导程序下拉框。当我们点击另一个下拉菜单时&#xff0c;其中一个会根据用户选择的国家显示来自数据库的所有国家名称&#xff0c;另一个下拉菜单应该选择状态。 当我点击一个下拉菜单时&#xff0c;我做了一个ajax请求来显示国家名称。如何根据国家选择触发其他下拉菜…

使用apache服务器配置虚拟目录

安装好了apachephpmysql之后就像在自己电脑上安装wordpress玩玩&#xff0c;因为安装好之后根目录在D盘&#xff0c; 所以就想自己配置一个虚拟目录指向路径为D:\wordpress的wordpress 在httpd.conf中添加虚拟目录之后去访问localhost:88/myblog却出现了403错误&#xff0c;提示…

YARN的HA

拓展&#xff1a;线程与进程的区别 进程是由一个以上的的线程组成的 ps -ef 能出现的就是进程。 YARN HA hadoop001&#xff1a;zk rm(zkfc) nmhadoop002&#xff1a;zk rm(zkfc) nmhadoop003&#xff1a;zk nm ZKFC: 线程 只作为RM进程的一个线程而非独立的进程存在 RMStateSt…

一个复杂的存储过程

首先说明一下我这个存储过程的功能&#xff1a; 根据不同的查询条件组合进行查询数据&#xff0c;数据库中有项目信息表Project 有项目区域表ProjectArea 项目信息表Project和项目区域表的关联是通过ProjectArea和AreaID进行一对一关联&#xff0c;项目区域信息中的信息有所属关…

Go 分布式学习利器(13)-- Go语言的多态

文章目录1. 基本的多态实现2. 空接口与断言3. Go接口的最佳实践1. 基本的多态实现 我们知道C中实现多态是通过虚函数表 和 继承来 实现的。 类似如下代码&#xff1a; class Programmar{ public:virtual void write_hello_world() 0; }class GoProgrammar: public Programma…

服务器搭建虚拟win云服务,云服务器创建win10虚拟机

云服务器创建win10虚拟机 内容精选换一换弹性云服务器(Elastic Cloud Server&#xff0c;以下简称ECS)是由CPU、内存、镜像、云硬盘组成的一种可随时获取、弹性可扩展的计算服务器&#xff0c;同时它结合VPC、虚拟防火墙、数据多副本保存等能力&#xff0c;为您打造一个高效、可…

预编译 ASP.NET 网站以进行部署

预编译 ASP.NET 网站以进行部署和更新 打开一个命令窗口并定位到包含 .NET Framework 的文件夹。 .NET Framework 将安装在以下位置。 %windir%\Microsoft.NET\Framework\version运行 aspnet_compiler 命令&#xff0c;在命令提示符下键入以下内容&#xff0c;同时指定源&…

Go 分布式学习利器(14)-- Go语言的错误处理

1. Go 的错误机制 Go 语言的错误机制中与其他语言的主要差异如下&#xff1a; 没有异常机制error 类型实现了 error接口type error interface {Error() string }可以通过errors.New来快速创建错误实例errors.New(" num is not in range[0,100]")如下测试代码演示基…

30 个 php 操作 redis 常用方法代码例子

这篇文章主要介绍了 30 个 php 操作 redis 常用方法代码例子 , 本文其实不止 30 个方法 , 可以操作 string 类型、 list 类型和 set 类型的数据 , 需要的朋友可以参考下redis 的操作很多的,以前看到一个比较全的博客,但是现在找不到了。查个东西搜半天,下面整理一下php 处理 re…

电脑机时,电脑死机时,为啥会忍不住扇它一巴掌?

我们为什么会把自己的愤怒发泄在机器人呢&#xff1f;对于人们为何会打机器这个问题&#xff0c;国外媒体Hopes&Fears请教了很多专家&#xff0c;包括精神治疗医师、机械工程师、愤怒管理专家以及流行文化专家。有一场非常重要的会议就要召开了&#xff0c;你必须在五分钟时…

Android所有系统版本USB调试模式打开方法

参考 Android所有系统版本USB调试模式打开方法

docker(4)docker的网络,自定义网桥

Docker 的网络 运行 ifconfig 找到 docker0 : 虚拟网卡默认网卡名称为docker0 查看docker 的网桥&#xff1a; 我这里默认们没有进行安装 网桥管理设备&#xff1a;进行安装一下&#xff1b; yum install bridge-utils 命令&#xff1a;查看网桥crctl show: 注意上图中的i…

Go 分布式学习利器(15) -- Go 实现 深搜和广搜

强化语法&#xff0c;回顾算法。 通过Go语言实现 深度优先搜索 和 广度优先搜索&#xff0c;来查找社交网络中的三度好友关系&#xff08;三度指的是一个节点到 其相邻节点 到 其相邻节点的节点 &#xff0c;图递增三层好友关系&#xff09;。 涉及到的Go语言语法&#xff1a…

css背景属性

CSS背景&#xff1a; 属性 描述 background 简写属性&#xff0c;作用是将背景属性设置在一个声明中。 background-attachment 背景图像是否固定或者随着页面的其余部分滚动。 background-color 设置元素的背景颜色。 background-image 把图像设置为背景。 backgroun…

scp服务器复制命令跳过已有的文件夹,Linux scp命令复制文件到其它服务器上

例如&#xff1a;我想将59.64.30.101中的文件复制到59.64.28.78服务器。步骤如下&#xff1a;1.59.64.30.101终端执行如下命令#ssh-keygen -t rsa2.密钥生成后会在/root/.ssh/文件夹下产生两个文件id_rsa id_rsa.pub将id_rsa.pub文件复制到59.64.28.78执行如下命令scp id_rsa.p…

Win2008学习(二),群集的仲裁配置

当群集中的节点发生故障时&#xff0c;会有其它节点继续提供服务。不过&#xff0c;当节点之间的通信有问题或太多故障节点时&#xff0c;群集服务就会停止&#xff0c;可是群集可以容纳多少个节点故障呢&#xff1f;这要由仲裁配置&#xff08;Quorum Configuration&#xff0…

前端token刷新并发处理

添加中间件&#xff0c;处理多个前端来的请求时&#xff0c;如果token需要刷新&#xff0c;先查看缓存&#xff0c;如果没有就在redis中做个标志位进行短期缓存&#xff0c;其他的请求发现缓存中的token&#xff0c;就不再刷新token了。这样就避免了重复刷新token的问题。 中间…

Rocksdb 的一些参数调优策略

文章目录写性能优化CF write buffer sizeDB write buffer size读性能优化block cachebloom filterCompression 压缩Compaction优化通用workload的配置本文在rocksdb 整个读写链路基础上给出一些简单的调优策略&#xff0c;主要是通过调整一些 参数来满足我们大多数workload的性…

Java项目:酒店管理系统(java+SSM+jsp+mysql+maven)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 主要技术:java springmvc mybatis mysql tomcat js jauery jsp log4j等一些常见基本技术适用于Java毕设和学习使用 主要实现&#xff1a; 前台&#xff1a;登录、注册、酒店信息浏览、搜索酒店信息…

设计模式之装饰模式(Java实现)

“怎么了&#xff0c;鱼哥&#xff1f;” “唉&#xff0c;别提了&#xff0c;网购了一件衣服&#xff0c;结果发现和商家描述的差太多了&#xff0c;有色差就算了&#xff0c;质量还不好&#xff0c;质量不好就算了&#xff0c;竟然大小也不行&#xff0c;说好的3个X&#xff…