当前位置: 首页 > news >正文

【JavaScript 算法】最长公共子序列:字符串问题的经典解法

在这里插入图片描述

🔥 个人主页:空白诗

在这里插入图片描述

文章目录

    • 一、算法原理
      • 状态转移方程
      • 初始条件
    • 二、算法实现
      • 注释说明:
    • 三、应用场景
    • 四、总结

在这里插入图片描述

最长公共子序列(Longest Common Subsequence,LCS)是字符串处理中的经典问题。给定两个字符串,找出它们的最长公共子序列,即在不改变字符顺序的情况下,从这两个字符串中抽取的最长的子序列。本文将详细介绍最长公共子序列的原理、实现及其应用。


一、算法原理

最长公共子序列问题可以通过动态规划(Dynamic Programming)来解决。其基本思想是构建一个二维数组 dp,其中 dp[i][j] 表示字符串 text1 的前 i 个字符和字符串 text2 的前 j 个字符的最长公共子序列的长度。

状态转移方程

  1. 如果 text1[i-1] == text2[j-1],则 dp[i][j] = dp[i-1][j-1] + 1
  2. 如果 text1[i-1] != text2[j-1],则 dp[i][j] = max(dp[i-1][j], dp[i][j-1])

初始条件

  1. i == 0j == 0 时,dp[i][j] = 0,因为空字符串与任何字符串的公共子序列长度为0。

二、算法实现

Longest Common Subsequence Flowchart

以下是最长公共子序列的JavaScript实现:

/*** 动态规划实现最长公共子序列* @param {string} text1 - 第一个字符串* @param {string} text2 - 第二个字符串* @return {number} - 最长公共子序列的长度*/
function longestCommonSubsequence(text1, text2) {const m = text1.length;const n = text2.length;const dp = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0)); // 初始化 dp 数组for (let i = 1; i <= m; i++) {for (let j = 1; j <= n; j++) {if (text1[i - 1] === text2[j - 1]) {dp[i][j] = dp[i - 1][j - 1] + 1; // 状态转移方程} else {dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]); // 状态转移方程}}}return dp[m][n]; // 返回最长公共子序列的长度
}// 示例
const text1 = "abcde";
const text2 = "ace";
console.log(longestCommonSubsequence(text1, text2)); // 输出: 3

注释说明:

  1. 初始化dp数组

    • const dp = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0));:创建一个二维数组,大小为 (m+1) x (n+1),并初始化为0。
  2. 遍历字符串

    • for (let i = 1; i <= m; i++):遍历字符串 text1 的每个字符。
    • for (let j = 1; j <= n; j++):遍历字符串 text2 的每个字符。
  3. 状态转移方程

    • if (text1[i - 1] === text2[j - 1]):如果当前字符相同,则 dp[i][j] = dp[i - 1][j - 1] + 1
    • else dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);:如果当前字符不同,则 dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])
  4. 返回结果

    • return dp[m][n];:返回 dp 数组的最后一个元素,即最长公共子序列的长度。

三、应用场景

  1. 文本比较:在文本编辑器中比较两个文档的差异。
  2. 版本控制:在版本控制系统中比较两个版本的代码差异。
  3. 基因序列分析:在生物信息学中比较DNA序列的相似性。
  4. 数据比较:在数据分析中比较两个数据集的相似性。

四、总结

最长公共子序列是字符串处理中的经典问题,通过动态规划的方法,可以高效地解决这个问题。理解和掌握最长公共子序列的算法,可以应用于文本比较、版本控制、基因序列分析和数据比较等领域。


相关文章:

  • [数据集][目标检测]导盲犬拐杖检测数据集VOC+YOLO格式4635张2类别
  • RK3568 V1.4.0 SDK,USB OTG端子不能被电脑识别出adb设备,解决
  • “信息科技风险管理”和“IT审计智能辅助”两个大模块的部分功能详细介绍:
  • 抖音seo短视频矩阵源码系统开发搭建----开源+二次开发
  • 8、添加第三方包
  • Android --- Kotlin学习之路:协程的使用,什么是协程,为什么要用协程?(学习笔记)
  • Docker 和 k8s 之间是什么关系?
  • 通义千问AI模型对接飞书机器人-模型配置(2-1)
  • HarmonyOS ArkUi @CustomDialog 和promptAction.openCustomDialog踩坑以及如何选择
  • Python--PyMySQL 库基础操作笔记
  • LeetCode热题100(JavaScript)
  • HTTP状态码(HTTP Status Code)讲解
  • k8s上部署openvpn
  • IP地址:由电脑还是网线决定?
  • 【产品评测】海康威视(HIKVISION)NAS网络存储——简单评测
  • [ JavaScript ] 数据结构与算法 —— 链表
  • [deviceone开发]-do_Webview的基本示例
  • 2017 年终总结 —— 在路上
  • Angular数据绑定机制
  • ES6简单总结(搭配简单的讲解和小案例)
  • go append函数以及写入
  • IE报vuex requires a Promise polyfill in this browser问题解决
  • Kibana配置logstash,报表一体化
  • mysql 数据库四种事务隔离级别
  • Nginx 通过 Lua + Redis 实现动态封禁 IP
  • PHP的类修饰符与访问修饰符
  • 不发不行!Netty集成文字图片聊天室外加TCP/IP软硬件通信
  • 后端_MYSQL
  • 回流、重绘及其优化
  • 机器学习学习笔记一
  • 使用SAX解析XML
  • 使用阿里云发布分布式网站,开发时候应该注意什么?
  • 通信类
  • 云栖大讲堂Java基础入门(三)- 阿里巴巴Java开发手册介绍
  • elasticsearch-head插件安装
  • # include “ “ 和 # include < >两者的区别
  • # Swust 12th acm 邀请赛# [ A ] A+B problem [题解]
  • # 移动硬盘误操作制作为启动盘数据恢复问题
  • #Js篇:单线程模式同步任务异步任务任务队列事件循环setTimeout() setInterval()
  • #免费 苹果M系芯片Macbook电脑MacOS使用Bash脚本写入(读写)NTFS硬盘教程
  • (function(){})()的分步解析
  • (Matalb时序预测)PSO-BP粒子群算法优化BP神经网络的多维时序回归预测
  • (大众金融)SQL server面试题(1)-总销售量最少的3个型号的车及其总销售量
  • (十) 初识 Docker file
  • (学习日记)2024.04.04:UCOSIII第三十二节:计数信号量实验
  • (转)Spring4.2.5+Hibernate4.3.11+Struts1.3.8集成方案一
  • .class文件转换.java_从一个class文件深入理解Java字节码结构
  • .net core 3.0 linux,.NET Core 3.0 的新增功能
  • .netcore 如何获取系统中所有session_如何把百度推广中获取的线索(基木鱼,电话,百度商桥等)同步到企业微信或者企业CRM等企业营销系统中...
  • .NET建议使用的大小写命名原则
  • .Net下C#针对Excel开发控件汇总(ClosedXML,EPPlus,NPOI)
  • [ C++ ] 类和对象( 下 )
  • [AI]文心一言出圈的同时,NLP处理下的ChatGPT-4.5最新资讯
  • [AIGC] Redis基础命令集详细介绍
  • [APIO2015]巴厘岛的雕塑