详解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使用append合并两个数组的方法
Apr 28 Python
Flask框架的学习指南之开发环境搭建
Nov 20 Python
Python的mysql数据库的更新如何实现
Jul 31 Python
理论讲解python多进程并发编程
Feb 09 Python
PyQT实现菜单中的复制,全选和清空的功能的方法
Jun 17 Python
基于django传递数据到后端的例子
Aug 16 Python
Win下PyInstaller 安装和使用教程
Dec 25 Python
PyTorch加载预训练模型实例(pretrained)
Jan 17 Python
python使用梯度下降算法实现一个多线性回归
Mar 24 Python
Python3如何使用多线程升程序运行速度
Aug 11 Python
Python虚拟环境virtualenv创建及使用过程图解
Dec 08 Python
PyCharm Ctrl+Shift+F 失灵的简单有效解决操作
Jan 15 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
Win9x/ME下Apache+PHP安装配置
2006/10/09 PHP
php相当简单的分页类
2008/10/02 PHP
curl实现站外采集的方法和技巧
2014/01/31 PHP
深入理解PHP中的global
2014/08/19 PHP
javascript 打印内容方法小结
2009/11/04 Javascript
xss文件页面内容读取(解决)
2010/11/28 Javascript
javascript继承之为什么要继承
2012/11/10 Javascript
jquery eval解析JSON中的注意点介绍
2013/08/23 Javascript
js onmousewheel事件多次触发问题解决方法
2014/10/17 Javascript
jquery实现动态画圆
2014/12/04 Javascript
javascript实现设置、获取和删除Cookie的方法
2015/06/01 Javascript
Jquery插件之Fancybox丰富的弹出层效果附源码下载
2015/12/02 Javascript
Javascript实现通过选择周数显示开始日和结束日的实现代码
2016/05/30 Javascript
JavaScript实现翻页功能(附效果图)
2017/02/16 Javascript
Nodejs多站点切换Htpps协议详解及简单实例
2017/02/23 NodeJs
JS回调函数基本定义与用法实例分析
2017/05/24 Javascript
vue 里面使用axios 和封装的示例代码
2017/09/01 Javascript
vue实现个人信息查看和密码修改功能
2018/05/06 Javascript
vue2.0 下拉框默认标题设置方法
2018/08/22 Javascript
vue使用高德地图根据坐标定位点的实现代码
2019/08/22 Javascript
file-loader打包图片文件时路径错误输出为[object-module]的解决方法
2020/01/03 Javascript
爬山算法简介和Python实现实例
2014/04/26 Python
使用pdb模块调试Python程序实例
2015/06/02 Python
对pandas replace函数的使用方法小结
2018/05/18 Python
python模块hashlib(加密服务)知识点讲解
2019/11/25 Python
CSS3属性使网站设计增强同时不消弱可用性
2009/08/29 HTML / CSS
eBay美国官网:eBay.com
2020/10/24 全球购物
super()与this()的区别
2016/01/17 面试题
应用心理学个人的求职信
2013/12/08 职场文书
给面试官的感谢信
2014/02/01 职场文书
《美丽的黄昏》教学反思
2014/02/28 职场文书
关于爱国的标语
2014/06/24 职场文书
新学期标语
2014/06/30 职场文书
大学生交通专业求职信
2014/09/01 职场文书
vue-router中hash模式与history模式的区别
2021/06/23 Vue.js
MySQL约束超详解
2021/09/04 MySQL