详解Python最长公共子串和最长公共子序列的实现


Posted in Python onJuly 07, 2018

最长公共子串(The Longest Common Substring)

LCS问题就是求两个字符串最长公共子串的问题。解法就是用一个矩阵来记录两个字符串中所有位置的两个字符之间的匹配情况,若是匹配则为1,否则为0。然后求出对角线最长的1的序列,其对应的位置就是最长匹配子串的位置。

def find_lcsubstr(s1, s2): 
 m=[[0 for i in range(len(s2)+1)] for j in range(len(s1)+1)] #生成0矩阵,为方便后续计算,比字符串长度多了一列
 mmax=0  #最长匹配的长度
 p=0 #最长匹配对应在s1中的最后一位
 for i in range(len(s1)):
 for j in range(len(s2)):
  if s1[i]==s2[j]:
  m[i+1][j+1]=m[i][j]+1
  if m[i+1][j+1]>mmax:
   mmax=m[i+1][j+1]
   p=i+1
 return s1[p-mmax:p],mmax  #返回最长子串及其长度
 
print find_lcsubstr('abcdfg','abdfg')

运行得到输出:('dfg',3)

最长公共子序列 (The Longest Common Subsequence)

子串要求字符必须是连续的,但是子序列就不是这样。最长公共子序列是一个十分实用的问题,它可以描述两段文字之间的“相似度”,即它们的雷同程度,从而能够用来辨别抄袭。对一段文字进行修改之后,计算改动前后文字的最长公共子序列,将除此子序列外的部分提取出来,这种方法判断修改的部分,往往十分准确。
        解法就是用动态回归的思想,一个矩阵记录两个字符串中匹配情况,若是匹配则为左上方的值加1,否则为左方和上方的最大值。一个矩阵记录转移方向,然后根据转移方向,回溯找到最长子序列。

import numpy
def find_lcseque(s1, s2): 
 # 生成字符串长度加1的0矩阵,m用来保存对应位置匹配的结果
 m = [ [ 0 for x in range(len(s2)+1) ] for y in range(len(s1)+1) ] 
 # d用来记录转移方向
 d = [ [ None for x in range(len(s2)+1) ] for y in range(len(s1)+1) ] 
 
 for p1 in range(len(s1)): 
 for p2 in range(len(s2)): 
  if s1[p1] == s2[p2]:      #字符匹配成功,则该位置的值为左上方的值加1
  m[p1+1][p2+1] = m[p1][p2]+1
  d[p1+1][p2+1] = 'ok'     
  elif m[p1+1][p2] > m[p1][p2+1]: #左值大于上值,则该位置的值为左值,并标记回溯时的方向
  m[p1+1][p2+1] = m[p1+1][p2] 
  d[p1+1][p2+1] = 'left'     
  else:              #上值大于左值,则该位置的值为上值,并标记方向up
  m[p1+1][p2+1] = m[p1][p2+1]  
  d[p1+1][p2+1] = 'up'     
 (p1, p2) = (len(s1), len(s2)) 
 print numpy.array(d)
 s = [] 
 while m[p1][p2]:  #不为None时
 c = d[p1][p2]
 if c == 'ok':  #匹配成功,插入该字符,并向左上角找下一个
  s.append(s1[p1-1])
  p1-=1
  p2-=1 
 if c =='left': #根据标记,向左找下一个
  p2 -= 1
 if c == 'up':  #根据标记,向上找下一个
  p1 -= 1
 s.reverse() 
 return ''.join(s) 
print find_lcseque('abdfg','abcdfg')

得到输出结果:

详解Python最长公共子串和最长公共子序列的实现

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python读取Android permission文件
Nov 01 Python
Python配置文件解析模块ConfigParser使用实例
Apr 13 Python
Python的Django框架中if标签的相关使用
Jul 15 Python
Python单例模式的两种实现方法
Aug 14 Python
浅谈Django自定义模板标签template_tags的用处
Dec 20 Python
浅谈Python Opencv中gamma变换的使用详解
Apr 02 Python
Tensorflow 查看变量的值方法
Jun 14 Python
libreoffice python 操作word及excel文档的方法
Jul 04 Python
python利用7z批量解压rar的实现
Aug 07 Python
Pyspark获取并处理RDD数据代码实例
Mar 27 Python
python爬虫利用代理池更换IP的方法步骤
Feb 21 Python
python井字棋游戏实现人机对战
Apr 28 Python
python求最大连续子数组的和
Jul 07 #Python
python 平衡二叉树实现代码示例
Jul 07 #Python
详解python异步编程之asyncio(百万并发)
Jul 07 #Python
基于Python开发chrome插件的方法分析
Jul 07 #Python
Python实现基于C/S架构的聊天室功能详解
Jul 07 #Python
Python实现的txt文件去重功能示例
Jul 07 #Python
Django 多语言教程的实现(i18n)
Jul 07 #Python
You might like
php在项目中寻找代码的坏味道(综艺命名)
2012/07/19 PHP
简单实用的.net DataTable导出Execl
2013/10/28 PHP
php实现保存submit内容之后禁止刷新
2014/03/19 PHP
利用PHP判断文件是否为图片的方法总结
2017/01/06 PHP
PHP聚合式迭代器接口IteratorAggregate用法分析
2017/12/28 PHP
PHP设计模式之状态模式定义与用法详解
2018/04/02 PHP
php实现算术验证码功能
2018/12/05 PHP
laravel实现图片上传预览,及编辑时可更换图片,并实时变化的例子
2019/11/14 PHP
学习面向对象之面向对象的基本概念:对象和其他基本要素
2010/11/30 Javascript
在js中判断checkboxlist(.net控件客户端id)是否有选中
2013/04/11 Javascript
JavaScript获取路径设计源码
2014/05/22 Javascript
javascript html5 canvas实现可拖动省份的中国地图
2016/03/11 Javascript
jQuery实现拖拽可编辑模块功能代码
2017/01/12 Javascript
jQuery中的一些小技巧
2017/01/18 Javascript
vue实现重置表单信息为空的方法
2018/09/29 Javascript
微信小程序引入Vant组件库过程解析
2019/08/06 Javascript
JavaScript编写开发动态时钟
2020/07/29 Javascript
python字典序问题实例
2014/09/26 Python
python类继承用法实例分析
2014/10/10 Python
Python 记录日志的灵活性和可配置性介绍
2018/02/27 Python
centos6.8安装python3.7无法import _ssl的解决方法
2018/09/17 Python
pytorch使用 to 进行类型转换方式
2020/01/08 Python
使用TensorFlow对图像进行随机旋转的实现示例
2020/01/20 Python
基于HTML5 Canvas:字符串,路径,背景,图片的详解
2013/05/09 HTML / CSS
《燕子》教学反思
2014/02/18 职场文书
心理学专业求职信
2014/06/16 职场文书
乡镇干部个人对照检查材料(群众路线)
2014/09/26 职场文书
人身损害赔偿协议书范本
2014/09/27 职场文书
三年级学生期末评语
2014/12/26 职场文书
杭州西湖英语导游词
2015/02/03 职场文书
2015年前台个人工作总结
2015/04/03 职场文书
五星红旗迎风飘扬观后感
2015/06/17 职场文书
检讨书怎么写?
2019/06/21 职场文书
nginx网站服务如何配置防盗链(推荐)
2021/03/31 Servers
分析Netty直接内存原理及应用
2021/06/14 Java/Android
Python编程中Python与GIL互斥锁关系作用分析
2021/09/15 Python