详解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 相关文章推荐
pygame学习笔记(3):运动速率、时间、事件、文字
Apr 15 Python
Python+django实现文件下载
Jan 17 Python
python+pandas分析nginx日志的实例
Apr 28 Python
使用Django启动命令行及执行脚本的方法
May 29 Python
python3实现猜数字游戏
Dec 07 Python
python脚本开机自启的实现方法
Jun 28 Python
使用python客户端访问impala的操作方式
Mar 28 Python
python如何求圆的面积
Jul 01 Python
详解Python IO编程
Jul 24 Python
python+selenium 简易地疫情信息自动打卡签到功能的实现代码
Aug 22 Python
scrapy redis配置文件setting参数详解
Nov 18 Python
Python3.8.2安装包及安装教程图文详解(附安装包)
Nov 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
在PHP3中实现SESSION的功能(一)
2006/10/09 PHP
劣质的PHP代码简化
2010/02/08 PHP
PHP开发需要注意的安全问题
2010/09/01 PHP
PHPThumb图片处理实例
2014/05/03 PHP
destoon实现调用当前栏目分类及子分类和三级分类的方法
2014/08/21 PHP
Laravel Validator自定义错误返回提示消息并在前端展示
2019/05/09 PHP
JavaScript学习笔记记录我的旅程
2012/05/23 Javascript
使用jQuery避免鼠标双击的解决方案
2013/08/21 Javascript
javascript中负数算术右移、逻辑右移的奥秘探索
2013/10/17 Javascript
自己动手实现jQuery Callbacks完整功能代码详解
2013/11/25 Javascript
JQuery设置时间段下拉选择实例
2014/12/30 Javascript
ajax如何实现页面局部跳转与结果返回
2015/08/24 Javascript
JS日期对象简单操作(获取当前年份、星期、时间)
2016/10/26 Javascript
Node.js中用D3.js的方法示例
2017/01/16 Javascript
php输出全部gb2312编码内的汉字方法
2017/03/04 Javascript
React服务端渲染(总结)
2017/07/01 Javascript
vue-vuex中使用commit提交mutation来修改state的方法详解
2018/09/16 Javascript
微信小程序云开发之数据库操作
2019/05/18 Javascript
Python实现简单的代理服务器
2015/07/25 Python
用python编写第一个IDA插件的实例
2018/05/29 Python
Python设计模式之桥接模式原理与用法实例分析
2019/01/10 Python
Python正则表达式实现简易计算器功能示例
2019/05/07 Python
pytorch 实现张量tensor,图片,CPU,GPU,数组等的转换
2020/01/13 Python
Tensorflow 1.0之后模型文件、权重数值的读取方式
2020/02/12 Python
PyCharm2020.3.2安装超详细教程
2021/02/08 Python
HUGO BOSS美国官方网上商店:世界知名奢侈品牌
2017/08/04 全球购物
一套带答案的C++笔试题
2014/01/10 面试题
会计实习生工作总结的自我评价
2013/10/07 职场文书
教师职业道德事迹材料
2014/08/18 职场文书
北京天坛导游词
2015/02/12 职场文书
会议简报格式范文
2015/07/20 职场文书
关于运动会的广播稿
2015/08/19 职场文书
Python内置数据类型中的集合详解
2022/03/18 Python
Go语言 详解net的tcp服务
2022/04/14 Golang
Win11快速关闭所有广告推荐
2022/04/19 数码科技
Redis实现分布式锁的五种方法详解
2022/06/14 Redis