最长公共子序列
时间:2022-07-28
本文章向大家介绍最长公共子序列,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
最长公共子序列(Longest Commom Subsequence)
问题:最长公共子序列(Longest Commom Subsequence, LCS)查找以相同顺序在给定两个序列中存在的最长子序列的问题。
与子字符串不同,不需要子序列占据原始序列中的连续位置。
例如:
X:ABCBDAB
Y:BDCABA
那么,序列A和序列B的:
- 最长公共子序列的长度为4
- 最长公共子序列:BDAB、BCAB、BCBA
朴素解法
检查X[1..m]的每个子序列是否也是Y[1..n]的子序列。
由于X可能有2m个子序列,因此该解放方法的复杂度将为O(n*2m)。
LCS问题的最优子结构
class LCS
{
// Function to find length of Longest Common Subsequence of
// sequences X[0..m-1] and Y[0..n-1]
public static int LCSLength(String X, String Y, int m, int n)
{
// return if we have reached the end of either sequence
if (m == 0 || n == 0) {
return 0;
}
// if last character of X and Y matches
if (X.charAt(m - 1) == Y.charAt(n - 1)) {
return LCSLength(X, Y, m - 1, n - 1) + 1;
}
// else if last character of X and Y don't match
return Integer.max(LCSLength(X, Y, m, n - 1),
LCSLength(X, Y, m - 1, n));
}
// main function
public static void main(String[] args)
{
String X = "ABCBDAB", Y = "BDCABA";
System.out.print("The length of LCS is "
+ LCSLength(X, Y, X.length(), Y.length()));
}
}
import java.util.HashMap;
import java.util.Map;
class LCS
{
// Function to find length of Longest Common Subsequence of substring
// X[0..m-1] and Y[0..n-1]
public static int LCSLength(String X, String Y, int m, int n,
Map<String, Integer> lookup)
{
// return if we have reached the end of either string
if (m == 0 || n == 0)
return 0;
// construct an unique map key from dynamic elements of the input
String key = m + "|" + n;
// if sub-problem is seen for the first time, solve it and
// store its result in a map
if (!lookup.containsKey(key))
{
// if last character of X and Y matches
if (X.charAt(m - 1) == Y.charAt(n - 1)) {
lookup.put(key, LCSLength(X, Y, m - 1, n - 1, lookup) + 1);
}
else {
// else if last character of X and Y don't match
lookup.put(key, Integer.max(LCSLength(X, Y, m, n-1, lookup),
LCSLength(X, Y, m-1, n, lookup)));
}
}
// return the subproblem solution from the map
return lookup.get(key);
}
// main function
public static void main(String[] args)
{
String X = "ABCBDAB", Y = "BDCABA";
// create a map to store solutions of subproblems
Map<String, Integer> lookup = new HashMap<>();
System.out.print("The length of LCS is "
+ LCSLength(X, Y, X.length(), Y.length(), lookup));
}
}
class LCS
{
// Function to find length of Longest Common Subsequence of substring
// X[0..m-1] and Y[0..n-1]
public static int LCSLength(String X, String Y)
{
int m = X.length(), n = Y.length();
// lookup table stores solution to already computed sub-problems
// i.e. T[i][j] stores the length of LCS of substring
// X[0..i-1] and Y[0..j-1]
int[][] T = new int[m + 1][n + 1];
// fill the lookup table in bottom-up manner
for (int i = 1; i <= m; i++)
{
for (int j = 1; j <= n; j++)
{
// if current character of X and Y matches
if (X.charAt(i - 1) == Y.charAt(j - 1)) {
T[i][j] = T[i - 1][j - 1] + 1;
}
// else if current character of X and Y don't match,
else {
T[i][j] = Integer.max(T[i - 1][j], T[i][j - 1]);
}
}
}
// LCS will be last entry in the lookup table
return T[m][n];
}
// main function
public static void main(String[] args)
{
String X = "XMJYAUZ", Y = "MZJAWXU";
System.out.print("The length of LCS is " + LCSLength(X, Y));
}
}
- [Longest Common Subsquence](https://www.techiedelight.com/longest-common-subsequence/
- Dynamic-programming from novice to advanced
- Golang事务模型
- 厚土Go学习笔记 | 35. web服务器实现动态路径
- 过滤器Filter精华知识点,怎能不看
- JavaMail开发示例,学习要看对资料
- 厚土Go学习笔记 | 34. 一个简单的 web 服务器实现
- sqlplus / as sysdba无法登录的奇怪报错 (r8笔记第36天)
- JSP与EL表达式重点学习笔记(1)
- R语言读CSV、txt文件方式以及read.table read.csv 和readr(大数据读取包)
- JSP与EL表达式重点学习笔记(2)
- Node.js真的无所不能?那些不适用的应用领域分析
- #!/bin/bash 与#!/bin/sh
- 客户端无法连接数据库的小问题(r8笔记第53天)
- Golang事务模型
- 厚土Go学习笔记 | 35. web服务器实现动态路径
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Rust FFI 编程 - bindgen 使用示例
- bug 回忆录(三)
- bug 回忆录(二)
- bug 回忆录(一)
- 曾经绊倒我的 “超级丑数”
- Flutter 完成全平台制霸:实现 Windows 应用支持
- 尤大 4 天前发在 GitHub 上的 vue-lit 是啥?
- 原创的20个Python自动化案例,一口一个,高效办公!
- 看完这篇Python操作PPT总结,从此使用Python玩转Office全家桶就没有压力了!
- 【Hadoop 分布式部署 三:基于Hadoop 2.x 伪分布式部署进行修改配置文件】
- DCL单例模式你不知道的秘密
- 《大话数据结构》队列的顺序存储和链式存储
- 《大话数据结构》栈的顺序存储及链式存储
- 《大话数据结构》之双向链表
- 《大话数据结构》线性表的链式存储结构