详解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根据路径导入模块的方法
Sep 30 Python
python实现从字典中删除元素的方法
May 04 Python
总结网络IO模型与select模型的Python实例讲解
Jun 27 Python
使用Python & Flask 实现RESTful Web API的实例
Sep 19 Python
python 不以科学计数法输出的方法
Jul 16 Python
Python中staticmethod和classmethod的作用与区别
Oct 11 Python
python微信公众号之关注公众号自动回复
Oct 25 Python
python 使用装饰器并记录log的示例代码
Jul 12 Python
python与pycharm有何区别
Jul 01 Python
Django生成数据库及添加用户报错解决方案
Oct 09 Python
Pytest中skip和skipif的具体使用方法
Jun 30 Python
python unittest单元测试的步骤分析
Aug 02 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
博士208HAF收音机实习报告
2021/03/02 无线电
php生成4位数字验证码的实现代码
2015/11/23 PHP
PHP实现多关键字加亮功能
2016/10/21 PHP
laravel开发环境homestead搭建过程详解
2020/07/03 PHP
动态加载js文件 document.createElement
2006/10/14 Javascript
javascript 单选框,多选框美化代码
2008/08/01 Javascript
jQuery Clone Bug解决代码
2010/12/22 Javascript
css样式标签和js语法属性区别
2013/11/06 Javascript
浅析JS动态创建元素【两种方法】
2016/04/20 Javascript
jQuery增加和删除表格项目及实现表格项目排序的方法
2016/05/30 Javascript
JavaScript数组去重算法实例小结
2018/05/07 Javascript
vue微信分享到朋友圈 vue微信发送给好友
2018/11/28 Javascript
微信小程序云开发如何实现数据库自动备份实现
2019/08/16 Javascript
Vue通过配置WebSocket并实现群聊功能
2019/12/31 Javascript
python从ftp下载数据保存实例
2013/11/20 Python
利用信号如何监控Django模型对象字段值的变化详解
2017/11/27 Python
Python设计模式之观察者模式简单示例
2018/01/10 Python
flask中的wtforms使用方法
2018/07/21 Python
在pycharm中python切换解释器失败的解决方法
2018/10/29 Python
使用pyinstaller打包PyQt4程序遇到的问题及解决方法
2019/06/24 Python
Spring实战之使用util:命名空间简化配置操作示例
2019/12/09 Python
python 实现朴素贝叶斯算法的示例
2020/09/30 Python
Python实现疫情地图可视化
2021/02/05 Python
如何用 Python 制作一个迷宫游戏
2021/02/25 Python
东南亚排名第一的服务市场:kaodim
2019/03/28 全球购物
安全大检查反思材料
2014/01/31 职场文书
医学生求职信
2014/07/01 职场文书
统计专业自荐书
2014/07/06 职场文书
医学专业毕业生推荐信
2014/07/12 职场文书
诚信承诺书
2015/01/19 职场文书
2015年度电厂个人工作总结
2015/05/13 职场文书
2016应届毕业生实习心得体会
2015/10/09 职场文书
驾驶员安全责任协议书
2016/03/22 职场文书
python实现简单的聊天小程序
2021/07/07 Python
alibaba seata服务端具体实现
2022/02/24 Java/Android
2022年显卡天梯图(6月更新)
2022/06/17 数码科技