详解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设计模式编程中的访问者与观察者模式
Jan 26 Python
Python+Opencv识别两张相似图片
Mar 23 Python
利用Python开发微信支付的注意事项
Aug 19 Python
实践Vim配置python开发环境
Jul 02 Python
一看就懂得Python的math模块
Oct 21 Python
django celery redis使用具体实践
Apr 08 Python
Pandas中Series和DataFrame的索引实现
Jun 27 Python
python可视化爬虫界面之天气查询
Jul 03 Python
Python绘制频率分布直方图的示例
Jul 08 Python
Django用户身份验证完成示例代码
Apr 03 Python
PyInstaller运行原理及常用操作详解
Jun 13 Python
Pytorch1.5.1版本安装的方法步骤
Dec 31 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方法curl抓取AJAX异步内容思路分析及代码分享
2014/08/25 PHP
PHP中的静态变量及static静态变量使用详解
2015/11/05 PHP
PHP使用Pthread实现的多线程操作实例
2015/11/14 PHP
实现PHP框架系列文章(6)mysql数据库方法
2016/03/04 PHP
自制PHP框架之设计模式
2017/05/07 PHP
Laravel 简单实现Ajax滚动加载示例
2019/10/22 PHP
PHP基于phpqrcode类生成二维码的方法示例详解
2020/08/07 PHP
兼容ie和firefox js关闭代码
2008/12/11 Javascript
nodejs实现黑名单中间件设计
2014/06/17 NodeJs
原生javascript实现图片滚动、延时加载功能
2015/01/12 Javascript
jquery插件unobtrusive实现片段式加载
2015/06/15 Javascript
js判断PC端与移动端跳转
2020/12/24 Javascript
React学习之受控组件与数据共享实例分析
2020/01/06 Javascript
为什么JavaScript中0.1 + 0.2 != 0.3
2020/12/03 Javascript
[06:36]吞吞映像top1
2014/06/20 DOTA
Python的IDEL增加清屏功能实例
2017/06/19 Python
Python 内置函数进制转换的用法(十进制转二进制、八进制、十六进制)
2018/04/30 Python
基于python 微信小程序之获取已存在模板消息列表
2019/08/05 Python
Python3 venv搭建轻量级虚拟环境的步骤(图文)
2019/08/09 Python
python实现图片插入文字
2019/11/26 Python
新年福利来一波之Python轻松集齐五福(demo)
2020/01/20 Python
pycharm设置当前工作目录的操作(working directory)
2020/02/14 Python
python+requests接口压力测试500次,查看响应时间的实例
2020/04/30 Python
45个非常奇妙的CSS3 特性应用示例
2012/01/01 HTML / CSS
真正的英国宝藏:Mappin & Webb
2019/05/05 全球购物
斯图尔特·韦茨曼鞋加拿大官网:Stuart Weitzman加拿大
2019/10/13 全球购物
TecoBuy澳大利亚:在线电子和小工具商店
2020/06/25 全球购物
一套C#面试题
2013/10/09 面试题
大学本科毕业生求职简历的自我评价
2013/10/09 职场文书
大专毕业生简历的自我评价
2013/10/20 职场文书
《月光启蒙》教学反思
2014/03/01 职场文书
入党自荐书范文
2014/03/09 职场文书
电视节目策划方案
2014/05/16 职场文书
课外活动实习计划
2015/01/19 职场文书
《云雀的心愿》教学反思
2016/02/23 职场文书
Java中多线程下载图片并压缩能提高效率吗
2021/07/01 Java/Android