软件安全的一个小实验,正好复习一下LCS的写法。


实现LCS的算法和算法导论上的方式基本一致,都是先建好两个表,一个存储在(i,j)处当前最长公共子序列长度,另一个存储在(i,j)处的回溯方向。

相对于算法导论的版本,增加了一个多分支回溯,即存储回溯方向时出现了向上向左都可以的情况时,这时候就代表可能有多个最长公共子序列。当回溯到这里时,让程序带着存储已经回溯的字符串的栈进行递归求解,当走到左上角的时候输出出来


# coding=utf-8

class LCS():
def input(self, x, y):
#读入待匹配的两个字符串
if type(x) != str or type(y) != str:
print 'input error'
return None
self.x = x
self.y = y def Compute_LCS(self):
xlength = len(self.x)
ylength = len(self.y)
self.direction_list = [None] * xlength #这个二维列表存着回溯方向
for i in xrange(xlength):
self.direction_list[i] = [None] * ylength
self.lcslength_list = [None] * (xlength + 1)
#这个二维列表存着当前最长公共子序列长度
for j in xrange(xlength + 1):
self.lcslength_list[j] = [None] * (ylength + 1) for i in xrange(0, xlength + 1):
self.lcslength_list[i][0] = 0
for j in xrange(0, ylength + 1):
self.lcslength_list[0][j] = 0
#下面是进行回溯方向和长度表的赋值
for i in xrange(1, xlength + 1):
for j in xrange(1, ylength + 1):
if self.x[i - 1] == self.y[j - 1]:
self.lcslength_list[i][j] = self.lcslength_list[i - 1][j - 1] + 1
self.direction_list[i - 1][j - 1] = 0 # 左上
elif self.lcslength_list[i - 1][j] > self.lcslength_list[i][j - 1]:
self.lcslength_list[i][j] = self.lcslength_list[i - 1][j]
self.direction_list[i - 1][j - 1] = 1 # 上
elif self.lcslength_list[i - 1][j] < self.lcslength_list[i][j - 1]:
self.lcslength_list[i][j] = self.lcslength_list[i][j - 1]
self.direction_list[i - 1][j - 1] = -1 # 左
else:
self.lcslength_list[i][j] = self.lcslength_list[i - 1][j]
self.direction_list[i - 1][j - 1] = 2 # 左或上
self.lcslength = self.lcslength_list[-1][-1]
return self.direction_list, self.lcslength_list def printLCS(self, curlen, i, j, s):
if i == 0 or j == 0:
return None if self.direction_list[i - 1][j - 1] == 0:
if curlen == self.lcslength:
s += self.x[i - 1]
for i in range(len(s)-1,-1,-1):
print s[i],
print '\n'
elif curlen < self.lcslength:
s += self.x[i-1]
self.printLCS(curlen + 1, i - 1, j - 1, s)
elif self.direction_list[i - 1][j - 1] == 1:
self.printLCS(curlen,i - 1, j,s)
elif self.direction_list[i - 1][j - 1] == -1:
self.printLCS(curlen,i, j - 1,s)
else:
self.printLCS(curlen,i - 1, j,s)
self.printLCS(curlen,i, j - 1,s) def returnLCS(self):
#回溯的入口
self.printLCS(1,len(self.x), len(self.y),'') if __name__ == '__main__':
p = LCS()
p.input('abcbdab', 'bdcaba')
p.Compute_LCS()
p.returnLCS()

在对'abcbdab'和'bdcaba'两个串用LCS后,得到下面结果:

用python实现最长公共子序列算法(找到所有最长公共子串)的更多相关文章

  1. Luogu 3402 最长公共子序列(二分,最长递增子序列)

    Luogu 3402 最长公共子序列(二分,最长递增子序列) Description 经过长时间的摸索和练习,DJL终于学会了怎么求LCS.Johann感觉DJL孺子可教,就给他布置了一个课后作业: ...

  2. codevs 1862 最长公共子序列(求最长公共子序列长度并统计最长公共子序列的个数)

    题目描述 Description 字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列.令给定的字符序列X=“x0,x1,…,xm-1”,序列Y ...

  3. LCSS最长公共子序列算法

    0.论文基本介绍以及相关内容 分析移动用户位置的相似性,提取移动用户的相似路径在出行路径预测.兴趣区域发现.轨迹聚类.个性化路径推荐等领域具有广泛的应用. 重点:利用移动用户定位数据找到合适轨迹的表示 ...

  4. 【科技】位运算(bitset)优化最长公共子序列算法

    最长公共子序列(LCS)问题 你有两个字符串 \(A,B\),字符集为 \(\Sigma\),求 \(A, B\) 的最长公共子序列. 简单动态规划 首先有一个广为人知的 dp:\(f_{i,j}\) ...

  5. 动态规划经典——最长公共子序列问题 (LCS)和最长公共子串问题

    一.最长公共子序列问题(LCS问题) 给定两个字符串A和B,长度分别为m和n,要求找出它们最长的公共子序列,并返回其长度.例如: A = "HelloWorld"    B = & ...

  6. 最长递增子序列(lis)最长公共子序列(lcs) 最长公共上升子序列(lics)

    lis: 复杂度nlgn #include<iostream> #include<cstdio> using namespace std; ],lis[],res=; int ...

  7. 最长上升子序列算法(n^2 及 nlogn) (LIS) POJ2533Longest Ordered Subsequence

    问题描述: 一个数的序列bi,当b1 < b2 < ... < bS的时候,我们称这个序列是上升的.对于给定的一个序列(a1, a2, ..., aN),我们可以得到一些上升的子序列 ...

  8. 最长公共子序列(LCS)最长递增子序列(LIS)

    #include<cstring>#include<iostream>#include<stack>#include <algorithm>using ...

  9. 【ZH奶酪】如何用Python计算最长公共子序列和最长公共子串

    1. 什么是最长公共子序列?什么是最长公共子串? 1.1. 最长公共子序列(Longest-Common-Subsequences,LCS) 最长公共子序列(Longest-Common-Subseq ...

随机推荐

  1. Hive on Spark安装配置详解(都是坑啊)

    个人主页:http://www.linbingdong.com 简书地址:http://www.jianshu.com/p/a7f75b868568 简介 本文主要记录如何安装配置Hive on Sp ...

  2. spring boot 部署为jar

    前言 一直在ide中敲代码,使用命令行mvn spring-boot:run或者gradlew bootRun来运行spring boot项目.想来放到prod上面也应该很简单.然而今天试了下,各种问 ...

  3. JavaScript 正则表达式语法

    定义 JavaScript定义正则表达式有两种方法. 1.RegExp构造函数 var pattern = new RegExp("[bc]at","i"); ...

  4. 【每日一linux命令1】linux命令路径

    一.路径: 执行命令前必须要考虑的一步是命令的路径,若是路径错误或是没有正确的指定,可能导致错误 的执行或是找不到该命令.要知道设置的路径,可执行以下命令: echo $PATH 显示结果: 这时我们 ...

  5. angular中使用ngResource模块构建RESTful架构

    ngResource模块是angular专门为RESTful架构而设计的一个模块,它提供了'$resource'模块,$resource模块是基于$http的一个封装.下面来看看它的详细用法 1.引入 ...

  6. Java中的Checked Exception——美丽世界中潜藏的恶魔?

    在使用Java编写应用的时候,我们常常需要通过第三方类库来帮助我们完成所需要的功能.有时候这些类库所提供的很多API都通过throws声明了它们所可能抛出的异常.但是在查看这些API的文档时,我们却没 ...

  7. 再来说说 LaTeX

    在我的上一篇随笔中,我提到了 Markdown.LaTeX 和 MathJax.这几个东西对目前的网络技术文章的写作.展示都有深远的影响.在上一篇中,我还给出了一份 LaTeX 语法的学习资料.在这一 ...

  8. Linux 中的数值计算和符号计算

    不知道经常需要做科学计算的朋友们有没有这样的好奇:在 Linux 系统下使用什么工具呢?说到科学计算,首先想到的肯定是 Matlab,如果再说到符号计算,那就非 Mathematica 不可了.可惜, ...

  9. 曲演杂坛--蛋疼的ROW_NUMBER函数

    使用ROW_NUMBER来分页几乎是家喻户晓的东东了,而且这东西简单易用,简直就是程序员居家必备之杀器,然而ROW_NUMBER也不是一招吃遍天下鲜的无敌BUG般存在,最近就遇到几个小问题,拿出来供大 ...

  10. idea报错:error java compilation failed internal java compiler error

    idea下面报如下问题 error java compilation failed internal java compiler error 解决办法:Setting->Compiler-> ...