软件安全的一个小实验,正好复习一下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. 【小计】新人Tostring前忘记Null判断的处理

    ToString和string.Concat(可屏蔽Null的异常)性能相差不大,一些中小项目完全可以用Concat(新人容易忘记判断Null的情况,遇到太多了,所以建议重写tostring方法,内部 ...

  2. 06.SQLServer性能优化之---数据库级日记监控

    汇总篇:http://www.cnblogs.com/dunitian/p/4822808.html#tsql 之前说了一下数据库怎么发邮件:http://www.cnblogs.com/duniti ...

  3. Beanstalkd一个高性能分布式内存队列系统

    高性能离不开异步,异步离不开队列,内部是Producer-Consumer模型的原理. 设计中的核心概念: job:一个需要异步处理的任务,是beanstalkd中得基本单元,需要放在一个tube中: ...

  4. js获取给定月份的N个月后的日期

    1.在讲js获取给定月份的N个月后的日期之前,小颖先给大家讲下getFullYear().getYear()的区别. ①getYear() var d = new Date() console.log ...

  5. ASP.NET MVC5+EF6+EasyUI 后台管理系统(81)-数据筛选(万能查询)

    系列目录 前言 听标题的名字似乎是一个非常牛X复杂的功能,但是实际上它确实是非常复杂的,我们本节将演示如何实现对数据,进行组合查询(数据筛选) 我们都知道Excel中是如何筛选数据的.就像下面一样 他 ...

  6. 从netty-example分析Netty组件续

    上文我们从netty-example的Discard服务器端示例分析了netty的组件,今天我们从另一个简单的示例Echo客户端分析一下上个示例中没有出现的netty组件. 1. 服务端的连接处理,读 ...

  7. BPM应用开发解决方案分享

    一.需求分析企业整体管理是一个完整的体系,如果 把这个体系比做一个拼图,企业信息化通过各个业务系统覆盖了一部分业务. 企业通过采购实施通用软件的方式,覆盖了企业的核心业务和专业化业务然而系统只满足了部 ...

  8. Linux-Rhel6 恢复误删文件

    需要工具extundelete(可通过xshell上传下载到linux)知识点:ifconifig eth0             查看ipfdisk /dev/sda          管理磁盘m ...

  9. C++常考面试题汇总

    c++面试题 一 用简洁的语言描述 c++ 在 c 语言的基础上开发的一种面向对象编程的语言: 应用广泛: 支持多种编程范式,面向对象编程,泛型编程,和过程化编程:广泛应用于系统开发,引擎开发:支持类 ...

  10. 【初码干货】【Azure系列】1、再次感受Azure,体验Windows Server 2016并部署BlogEngine.NET

    上个月末,在某人的建议下,重新注册了一个1元试用账户(包含1个月期限的1500元订阅),并充值了1000元转为了正式账户,相当于1000元得到了2500的订阅,于是又一次开启了Azure之旅. 在这不 ...