算法学习 - 最长公共子序列(LCS)C++实现

article/2025/9/11 12:15:54

最长公共子序列

最长公共子序列的问题很简单,就是在两个字符串中找到最长的子序列,这里明确两个含义:

  1. 子串:表示连续的一串字符 。
  2. 子序列:表示不连续的一串字符。

所以这里要查找的是不连续的最长子序列,

动态规划

这里为什么要使用动态规划可以说一下,简单来说动态规划是为了降低时间复杂度的一种算法,申请一个额外空间,来保存每一个步骤的结果,最后从这些结果中找到最优的解。

这里有个问题就是:一般来说,当前的最优解,只与当前时刻和上一时刻有关系,和其他时刻没有关系,这样才能让动态规划发生作用,降低复杂度。

分析LCS

其实LCS看起来很麻烦,找不到思路,如果暴力破解可能要O(n^4)了,而这个题目使用动态规划的思想也非常简单,为何相比之前的问题不好找思路呢?

是因为之前的动态规划问题例如:背包问题,生产线问题,都是一维数组空间内的结果,规划到一个线性时间内,而这个题目需要O(m*n)的时间复杂度和空间复杂度。

所以其实就是进行m*n次对比,每次保存当前的最优解,就可以了。

代码实现分析

这里有个问题,就是我们需要的结果仅仅是长度? 还是包括这个序列串一起输出。

看下面图:

LCS构造矩阵图片

这里可以看到,我们构造的一个i*j的矩阵,这个矩阵里的内容不但包括数值(当前结果的最优解),还包括一个方向箭头,这个代表了我们回溯的时候,需要行走的方向。

所以我们这里保存两个值,可以使用两个二维矩阵,也可以使用一个结构体矩阵。

解法分析

其实这个题目在动态规划来理解,也非常简单。一个状态转移函数。

LCS状态转移函数

这个非常好理解,其中一个字符串为0的时候,那么肯定是0了。

当两个字符相等的时候,这个时候很好理解,举例来说:

abcdadcd,在遍历c的时候,发现前面只有a相等了,也就是1.
那么c相等,也就是abcadc在匹配的时候,一定比abad的长度大1,这个1就是c相等么。也就是相等的时候,是比c[i-1][j-1]1的。

下一个更好理解了,如果不相等,肯定就是找到上一个时刻对比最大的么。

代码

这个代码只输出了LCS的长度,而结果数组的方向我已经存储好了,想要遍历的,直接从后向前遍历数组就好了。

//
//  main.cpp
//  LCS
//
//  最长公共子序列(LCS)
//
//  Created by Alps on 15/8/23.
//  Copyright (c) 2015年 chen. All rights reserved.
//#include <iostream>using namespace std;/*
* 这里可以不定义长度,输入的字符串用string存储,然后利用string.c_str()来对字符串进行数组转化。 我这里为了方便没有这样做。
*/
#ifndef MAX_LENGTH
#define MAX_LENGTH 15 //定义字符串最大长度
#endifint MaxNum(int firstNum, int secondNum){return firstNum > secondNum ? firstNum : secondNum;
}//定义数组结构体
struct matrix{int num;int direct;
};typedef matrix Matrix;int LCS(char *strA, char *strB, int lengthA, int lengthB, Matrix *resultMatrix[]){if (lengthA == 0 || lengthB == 0) {return 0;}for (int i = 0; i < lengthA; i++) {for (int j = 0; j < lengthB; j++) {resultMatrix[i][j].num = 0; //设置所有默认的最长为0resultMatrix[i][j].direct = 1; //所有默认方向变成上 0斜上,1上,-1左}}for (int i = 0; i < lengthA; i++) {for (int j = 0; j < lengthB; j++) {if (strA[i] == strB[j]) {resultMatrix[i+1][j+1].num = resultMatrix[i][j].num + 1;resultMatrix[i+1][j+1].direct = 0;}else{resultMatrix[i+1][j+1].num = MaxNum(resultMatrix[i+1][j].num, resultMatrix[i][j+1].num);resultMatrix[i+1][j+1].direct = resultMatrix[i+1][j].num > resultMatrix[i][j+1].num ? 1 : -1;}}}return resultMatrix[lengthA][lengthB].num;
}int main(int argc, const char * argv[]) {char *strA = (char*)malloc(sizeof(char) * MAX_LENGTH);char *strB = (char*)malloc(sizeof(char) * MAX_LENGTH);scanf("%s",strA);scanf("%s",strB);int lengthA = (int)strlen(strA);int lengthB = (int)strlen(strB);Matrix *resultMatrix[lengthA+1];for (int i = 0; i <= lengthA; i++) {resultMatrix[i] = (Matrix*)malloc(sizeof(struct matrix)* (lengthB+1));}int max = LCS(strA, strB, lengthA, lengthB, resultMatrix);printf("%d\n",max);std::cout << "Hello, World!\n";return 0;
}

以上。©Alps1992


http://chatgpt.dhexx.cn/article/OFOkHj2i.shtml

相关文章

SLIC算法介绍

SLIC&#xff08;simple linear iterativeclustering&#xff09;&#xff0c;即 简单线性迭代聚类 。 &#x1f49b;它是2010年提出的一种思想简单、实现方便的算法&#xff0c;将彩色图像转化为CIELAB颜色空间和XY坐标下的5维特征向量&#xff0c;然后对5维特征向量构造距离度…

LSC算法

1.问题 给定序列 X<x_1,x_2,…,x_m> Y<y_1,y_2,…,y_j> 求X和Y的最长公共子序列(LCS) 2.解析 X<x1,x2,x3,x4…,xi> Y<y1,y2,y3,y4…,yi> 如果Z<z1,z2,z3,z4…,zk>是他们的最长公共子序列 则&#xff1a; &#xff08;1&#xff09;xi yi&…

LCS算法详解

程序员编程艺术第十一章&#xff1a;最长公共子序列(LCS)问题 0、前言 程序员编程艺术系列重新开始创作了&#xff08;前十章&#xff0c;请参考程序员编程艺术第一~十章集锦与总结&#xff09;。回顾之前的前十章&#xff0c;有些代码是值得商榷的&#xff0c;因当时的代码只顾…

LCS 最大公共序列算法

这些天在了解chrome的courgette, 了解了rsync算法, 也了解了courgette使用了bsdiff 算法, 然后知道了bsdiff算法里主要使用的是 LCS 算法, 这里参考了july大牛的文章: http://blog.csdn.net/v_july_v/article/details/6695482 自己做一点概括性的总结, 用以备忘, 也把自…

最长公共子序列(LCS)算法

一、最长公共字串与最长公共子序列 最长公共子串&#xff08;Longest Common Substirng&#xff09; 子串是串的一个连续的部分&#xff0c;子串中字符的位置必须连续。 例如&#xff1a;有两个字符串ABCBDAB 和 BDCABA&#xff0c;则它们的最长公共子串是&#xff1a;AB。 …

LCS(longest common sequence)算法的实现(十分详细)

一、问题描述 有两个字符串&#xff0c;求二者的最长公共子序列。 最长公共子序列&#xff1a;不必连续但必须有序的子列&#xff08;与子串区分&#xff0c;子串是连续的&#xff09; 二&#xff1a;解决方法 第一种方法&#xff1a;穷举法 &#xff0c;就是一个一个的对比&a…

LCS算法

LCS算法 LCS算法&#xff1a; LCS是Longest Common Subsequence的缩写&#xff0c;即最长公共子序列。一个序列&#xff0c;如果是两个或多个已知序列的子序列&#xff0c;且是所有子序列中最长的&#xff0c;则为最长公共子序列。LCS不是唯一的&#xff0c;它可以有很多种&am…

Oracle中索引的原理

索引的概念 索引是一种数据库结构&#xff0c;能够就数据库中的某列提供快速查询&#xff0c;而不用检索整个表格&#xff08;官方的不行&#xff09;。 在 Oracle 数据库中&#xff0c;存储的每一行数据都有一个 rowID 来标识。当 Oracle 中存储着大量的数据时&#xff0c;意…

MongoDB索引原理及实践

背景 数据库的演进 随着计算机的发展&#xff0c;越来越多的数据需要被处理&#xff0c;数据库是为处理数据而产生。从概念上来说&#xff0c;数据库是指以一定的方式存储到一起&#xff0c;能为多个用户共享&#xff0c;具有更可能小的冗余&#xff0c;与应用程序彼此独立的…

MySql存储引擎和索引原理

转载 https://blog.csdn.net/tongdanping/article/details/79878302 注意&#xff1a; 1、索引需要占用磁盘空间&#xff0c;因此在创建索引时要考虑到磁盘空间是否足够 2、创建索引时需要对表加锁&#xff0c;因此实际操作中需要在业务空闲期间进行 MySQL支持诸多存储引擎&a…

MySQL之索引原理

1 简介 索引底层就是一种数据结构&#xff0c;空间换时间&#xff0c;能够帮助我们快速定位到对应的数据&#xff0c;就类似于字典里面的目录一样。 索引虽然能快速检索数据&#xff0c;但会影响数据修改的操作&#xff0c;而且索引存储在具体的文件&#xff0c;占用一定的空…

深入浅出数据库索引原理

使用索引很简单&#xff0c;只要能写创建表的语句&#xff0c;就肯定能写创建索引的语句&#xff0c;要知道这个世界上是不存在不会创建表的服务器端程序员的。然而&#xff0c; 会使用索引是一回事&#xff0c; 而深入理解索引原理又能恰到好处使用索引又是另一回事&#xff0…

MySQL索引原理和实现

说到索引&#xff0c;很多人都知道“索引是一个排序的列表&#xff0c;在这个列表中存储着索引的值和包含这个值的数据所在行的物理地址&#xff0c;在数据十分庞大的时候&#xff0c;索引可以大大加快查询的速度&#xff0c;这是因为使用索引后可以不用扫描全表来定位某行的数…

倒排索引原理,即为什么叫倒排索引

倒排索引的英文原名是Inverted index&#xff0c;大概因为Invert有颠倒的意思&#xff0c;所以就被翻译成了倒排&#xff0c;然后我们就会在字面上出现误解&#xff1a;理解为从A-Z颠倒成Z-A。其实它并不是字面上的意思。 倒排索引源于实际应用中需要根据属性的值来查找记录&a…

【数据库】数据库索引原理

正确的创建合适的索引 是提升数据库查询性能的基础 文章目录 1.索引是什么&#xff1f;2.为什么&#xff1f;3.索引原理B tree 4.B tree 在两大引擎中的体现5.索引的原则 1.索引是什么&#xff1f; 索引是为了加速对表中数据行的检索而创建的一种分散存储的数据结构。 2.为…

Mysql数据库的索引原理

写在前面&#xff1a;索引对查询的速度有着至关重要的影响&#xff0c;理解索引也是进行数据库性能调优的起点。考虑如下情况&#xff0c;假设数据库中一个表有10^6条记录&#xff0c;DBMS的页面大小为4K&#xff0c;并存储100条记录。如果没有索引&#xff0c;查询将对整个表进…

MySql索引原理与使用大全

林炳文Evankaka原创作品。转载请注明出处http://blog.csdn.net/evankaka 一、索引介绍 索引是对数据库表中一列或多列的值进行排序的一种结构。在关系数据库中&#xff0c;索引是一种与表有关的数据库结构&#xff0c;它可以使对应于表的SQL语句执行得更快。索引的作用相…

MySQL:索引原理

文章目录 1、索引概念1.1、使用场景1.2、索引代价 2、索引分类2.1、数据结构2.2、物理存储回表查询 & 覆盖索引 2.3、字段&#xff08;列&#xff09;属性2.3.1、主键索引主键的选择 2.3.2、唯一索引2.3.2、普通索引2.3.3、前缀索引 2.4、字段&#xff08;列&#xff09;个…

索引的原理和实现的方式

建立索引 需要有索引的类型和索引的方法。 索引的类型包括了Normal Unique Full text 而索引的方法包括了BTREE 和HASH 转载文章&#xff1a;https://www.cnblogs.com/aspwebchh/p/6652855.html 博主写的真好~ 一、什么是Btree B tree &#xff08;非二叉&#xff09; 了…

索引的实现原理

这篇文章是介绍MySQL数据库中的索引是如何根据需求一步步演变最终成为B树结构的以及针对B树索引的查询&#xff0c;插入&#xff0c;删除&#xff0c;更新等操作的处理方法。Oracle和DB2数据库索引的实现基本上也是大同小异的。文章写得很通俗易懂&#xff0c;就转在这了。关于…