最长公共子序列(LCS)算法
一、最长公共字串与最长公共子序列
最长公共子串(Longest Common Substirng)
子串是串的一个连续的部分,子串中字符的位置必须连续。
例如:有两个字符串ABCBDAB 和 BDCABA,则它们的最长公共子串是:AB。
最长公共子序列(Longest Common Subsequence,LCS)
子序列是从串中去掉任意的元素而获得新的序列,子串中字符的位置不必连续。
例如:有两个字符串ABCBDAB 和 BDCABA,则它们的最长公共子序列是:BCAB。
二、LCS算法
step1:生成矩阵
创建一个大小为str1_len×str2_len的矩阵,其中str1_len
和str2_len
分别为串str1和串str2的长度,初始化为0。
按照以下规则生成矩阵:
i和j分别从1开始,i++,j++循环:
如果
str1[i] == str2[j]
,则L[i,j] = L[i - 1, j -1] + 1
;如果
str1[i] != str2[j]
,则L[i,j] = max{L[i,j - 1],L[i - 1, j]}
;
void init_array(char *str1, char *str2) {int i,j;for(i=1; i<=str1_len; i++)for(j=1; j<=str2_len; j++) {if(str1[i-1] == str2[j-1])a[i][j] = a[i-1][j-1] + 1;else {if(a[i][j-1] >= a[i-1][j])a[i][j] = a[i][j-1];elsea[i][j] = a[i-1][j];}}
}
step2:计算公共子序列
按照以下规则计算公共子序列:
i
和j
分别从str1_len
,str2_len
开始,递减循环直到i = 0,j = 0
。
如果
str1[i-1] == str2[j-1]
,则将str[i]字符插入到子序列中,i--,j--
;如果
str1[i-1] != str[j-1]
,则比较L[i,j-1]
与L[i-1,j]
,L[i,j-1]
大,则j--
,否则i--
;(如果相等,则任选一个)
void parser(char *str1, char *str2, char *res) {int i,j,k = 0;for(i = str1_len, j = str2_len; i >= 1 && j >= 1;) {if(str1[i-1] == str2[j-1]) {res[k++] = str1[i-1];i--;j--;} elseif (a[i][j-1] > a[i-1][j])j--;elsei--;}
}
step3:逆序存放公共子序列
step2
得到的公共子序列是从后往前获得的,需要逆序存放或输出。
char* reverse(char *str) {int n = strlen(str) / 2;int i = 0;char tmp;for(i=0; i<n; i++) {tmp = str[i];str[i] = str[strlen(str)-i-1];str[strlen(str)-i-1] = tmp;}return str;
}
三、完整代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>#define MAX_LEN 256int str1_len, str2_len;
int a[MAX_LEN][MAX_LEN];void init_str(char *str1, char *str2) {printf("please input str1: ");scanf("%s", str1);printf("please input str2: ");scanf("%s", str2);
}void init_array(char *str1, char *str2) {int i,j;for(i=1; i<=str1_len; i++)for(j=1; j<=str2_len; j++) {if(str1[i-1] == str2[j-1])a[i][j] = a[i-1][j-1] + 1;else {if(a[i][j-1] >= a[i-1][j])a[i][j] = a[i][j-1];elsea[i][j] = a[i-1][j];}}
}void parser(char *str1, char *str2, char *res) {int i,j,k = 0;for(i = str1_len, j = str2_len; i >= 1 && j >= 1;) {if(str1[i-1] == str2[j-1]) {res[k++] = str1[i-1];i--;j--;} elseif (a[i][j-1] > a[i-1][j])j--;elsei--;}
}char* reverse(char *str) {int n = strlen(str) / 2;int i = 0;char tmp;for(i=0; i<n; i++) {tmp = str[i];str[i] = str[strlen(str)-i-1];str[strlen(str)-i-1] = tmp;}return str;
}int main(void) {char str1[MAX_LEN], str2[MAX_LEN], *res;init_str(str1, str2);str1_len = strlen(str1);str2_len = strlen(str2);init_array(str1, str2);res = (char*)malloc(sizeof(char) * (str1_len + str2_len));parser(str1, str2, res);printf("Result : %s\n", reverse(res));return 0;
}
四、牛刀小试
POJ 1458 Common Subsequence
Description
A subsequence of a given sequence is the given sequence with some elements (possible none) left out. Given a sequence X = < x1, x2, …, xm > another sequence Z = < z1, z2, …, zk > is a subsequence of X if there exists a strictly increasing sequence < i1, i2, …, ik > of indices of X such that for all j = 1,2,…,k, xij = zj. For example, Z = < a, b, f, c > is a subsequence of X = < a, b, c, f, b, c > with index sequence < 1, 2, 4, 6 >. Given two sequences X and Y the problem is to find the length of the maximum-length common subsequence of X and Y.
Input
The program input is from the std input. Each data set in the input contains two strings representing the given sequences. The sequences are separated by any number of white spaces. The input data are correct.
Output
For each set of data the program prints on the standard output the length of the maximum-length common subsequence from the beginning of a separate line.
Sample Input
abcfbc abfcab
programming contest
abcd mnp
Sample Output
4
2
0
Code
import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);while (sc.hasNext()) {String[] tmp = sc.nextLine().trim().split("\\s+");String str1 = tmp[0];String str2 = tmp[1];int[][] data = new int[str1.length() + 1][str2.length() + 1];for (int i = 1; i < data.length; i++)for (int j = 1; j < data[i].length; j++) {if (str1.charAt(i - 1) == str2.charAt(j - 1)) {data[i][j] = data[i - 1][j - 1] + 1;} else {data[i][j] = Math.max(data[i][j - 1], data[i - 1][j]);}}System.out.println(data[str1.length()][str2.length()]);}}
}
最长公共子序列(LCS)算法相关推荐
- 动态规划算法解最长公共子序列LCS问题
动态规划算法解LCS问题 作者 July 二零一零年十二月三十一日 本文参考:微软面试100题系列V0.1版第19.56题.算法导论.维基百科. 第一部分.什么是动态规划算法 ok,咱们先来了解下什么 ...
- 算法之最长公共子序列(LCS)问题
算法课上老师留的作业,最长公共子序列LCS(Longest Common Subsequence)问题,首先看到这个问题感觉有点复杂,和最长公共子串不同,公共子序列并不要求元素相邻,看起来只有穷举才能 ...
- 算法导论-----最长公共子序列LCS(动态规划)
目录 一.概念梳理 二.最长公共子序列解决方案 方案1:蛮力搜索策略 方案2:动态规划策略 三.C代码实现 实现1 实现2(空间优化) 一.概念梳理 1. 子序列(subsequence): 一个 ...
- 动态规划之最长公共子序列(LCS)
最长公共子序列(LCS,Longest Common Subsequence).其定义是,一个序列 S ,如果分别是两个或多个已知序列的子序列,且是所有符合此条件序列中最长的,则 S 称为已知序列的最 ...
- 程序员编程艺术第十一章:最长公共子序列(LCS)问题
程序员编程艺术第十一章:最长公共子序列(LCS)问题 0.前言 程序员编程艺术系列重新开始创作了(前十章,请参考程序员编程艺术第一~十章集锦与总结).回顾之前的前十章,有些代码是值得商榷的,因当时的代 ...
- python实现求解最长公共子序列LCS问题
在实现论文<Automatically Generating Models for Botnet Detection>论文的算法中,用到了一个The longest commom subs ...
- 动态规划表格法解决最长公共子序列(LCS)问题
3.5 最长公共子序列(LCS) 前言:图片是博主自己画的,转载请注明出处哦 3.5.1 问题描述 最长公共子序列(Longest Common Subseuence,LCS)问题:给定两个字符串,求 ...
- 最长公共子序列 (LCS) 详解+例题模板(全)
欢迎访问https://blog.csdn.net/lxt_Lucia-- 宇宙第一小仙女\(^o^)/-萌量爆表求带飞=≡Σ((( つ^o^)つ~ dalao们点个关注呗- ------------ ...
- 计算机算法设计与分析 动态规划 实验报告,动态规划法解最长公共子序列(计算机算法设计与分析实验报告).doc...
动态规划法解最长公共子序列(计算机算法设计与分析实验报告) 实报 告 实验名称:任课教师::姓 名:完成日期:二.主要实验内容及要求: 要求按动态规划法原理求解问题: 要求交互输入两个序列数据: 要求 ...
- 相似度:最长公共子序列--LCS
一.概念 1.子序列 一个特定序列的子序列就是将给定序列中零个或多个元素去掉后得到的结果(不改变元素间相对次序).如序列[A,B,C,B,D,A,B]的子序列有:[A,B],[B,C,A],[A,D, ...
最新文章
- 新建html带参数,本地html加载时带参数的问题
- 编码GBK的不可映射字符
- 周年直播倒计时2天,攒足惊喜等你开场! | MindSpore 开源一周年
- ConcurrentHashMap 和 Collections.synchronizedMap(map) 比较
- 微服务学习之服务治理、服务注册与发现、Eureka【Hoxton.SR1版】
- 大师级思考者是怎么探索事物本质的?
- 如何帮助空降经理人成功?
- android 串口调试工具,串口调试助手下载-串口调试助手下载v1.0.4 安卓版-西西软件下载...
- 猴子意念打字,有可能敲出莎士比亚全集
- 【转】金蝶EAS BOS工作流开发(附带JAVA脚本)
- AI大事件 | 谷歌的计算引擎鸟枪换炮用上了更快的GPU,基于Python的亚马逊AWS深度学习AMI
- 认识很浅的云南最后的秘境
- python实验过程心得体会_python学习心得
- 亚甲基蓝在胃肠道恶性肿瘤淋巴结检获中应用价值的Meta分析
- android背光系统,Android 的背光控制
- 读书报告1500字计算机大学篇,《活着》读后感_读书心得1500字大学篇
- Jasper(2)——简单使用导出PDF报表
- 大家好,我是区块链本人。今天,我要给你们介绍我的家族。
- uniapp uni-icons组件自定义图标
- css3 太极动画,纯css实现太极阴阳鱼动画