当前位置: 首页 > news >正文

Python Cookbook-5.13 寻找子序列

任务

需要在某大序列中查找子序列。

解决方案

如果序列是字符串(普通的或者Unicode),Python 的字符串的 find 方法以及标准库的re模块是最好的工具。否则,应该使用Knuth-Morris-Pratt算法(KMP):

def KnuthMorrisPratt(text,pattern):
'''在序列text中找到pattern的子序列的起始位置
	每个参数都可以是任何可迭代对象
	在每次产生一个结果时,对text的读取正好到达(包括)对pattern的一个匹配'''
	#确保能对pattern进行索引操作,同时制作pattern的一个拷贝,以防在生成结果时意外地修改pattern
	pattern = list(pattern)
	length = len(pattern)
	#创建KMP"移量表"并命名为shifts
	shifts = [1]*(length + 1)
	shift = 1
	for pos,pat in enumerate(pattern):
		while shift <= pos and pat != pattern[pos - shift]:
			shift += shifts[pos - shift]
		shifts[pos + 1] = shift
	#执行真正的搜索
	startPos = 0
	matchLen = 0
	for c in text:
		while matchLen == length or matchLen >= 0 and pattern[matchLen] != c:
			startPos += shifts[matchLen]
			matchLen -= shifts[matchLen]
		matchLen += 1
		if matchLen == length:yield startPos

讨论

本节实现的 Knuth-Morris-Pratt 算法可被用于在一个大文本的连续序列中查找某种指定的模式。由于 KMP 是以顺序的方式访问文本,所以很自然地,我们也可以将其应用于包括文本在内的任意可迭代对象。在处理阶段,算法会创建一个关于偏移量的表,它消耗的时间正比于模式的长度,而每个文本标志则以恒定的时间处理。在所有关于文本处理的基础算法书中都可以看到 KMP 算法的解释和示例。(更多资料一栏中也提供了推荐读物。)
如果 text 和 pattern 都是 Python 字符串,可以通过使用 Python 的内建搜索方法得到一个更快的方案:

def finditer(text,pattern):
	pos = -1
	while True:
		pos = text.find(pattern,pos+1)
		if pos <0:break
		yield pos

比如,使用一个长度为4的字母表(“ACGU”),在长度为100000的文本中查找长度为8的一个模式,在我的计算机上,借助 finditer 函数耗时为 4.3ms,但使用 KnuthMorrisPrat函数执行同样任务则需要540ms(在 Python2.3 中;而在 Python2.4 会快一些,约 480ms但仍然比 finditer 慢了超过 100倍)。所以请记住:本节的算法适用于在通用的序列中进行搜索,包括那些数据量大到无法放入内存的情况,如果只需要对字符串搜索Python 内建的搜索方法具有完全压倒性的优势。

http://www.dtcms.com/a/123212.html

相关文章:

  • 断言与反射——以golang为例
  • 深入剖析C++单例模式的八种实现演进与工程实践
  • 最新Ktransformers v0.24(Docker)并发部署DeepSeek-V3-0324模型
  • Cygwin编译安装Acise
  • 蓝桥杯省赛(2024)总结一下
  • 健康养生,铺就生命坦途
  • 深入理解 ResponseBodyAdvice 及其应用
  • Vue3+Vite+TypeScript+Element Plus开发-12.动态路由-配置
  • 【在校课堂笔记】Python 第 9 节课 总结
  • MySQL——锁
  • 可道云支持群晖的docker安装了:全网唯一支持onlyoffice安装说明
  • 如何制定合理的项目时间表
  • 本地电脑使用sshuttle命令将网络流量代理到ssh连接的电脑去实现访问受限网络
  • ubunut 20.04 Docker安装简易教学
  • 嵌入式八股---计算机网络篇
  • QT中怎么隐藏或显示最大化、最小化、关闭按钮
  • python爬取1688.item_search_best-查询榜单列表返回数据说明
  • KL散度的三种估计k1 k2 k3
  • 电子生产加工行业数字化转型:破局“多品种小批量”的智造跃迁
  • WinForm真入门(13)——ListBox控件详解
  • 天梯集训+代码打卡笔记整理
  • Apipost自定义函数深度实战:灵活处理参数值秘籍
  • 大模型训练关键两步
  • 物联网卡(NB-IoT/4G)技术详解
  • Flexoo 柔性薄膜加热片技术全解析:从原理到应用优势
  • Ubuntu 24.04 中文输入法安装
  • MIT6.828 Lab5 Copy-on-Write Fork for xv6
  • BUUCTF-web刷题篇(19)
  • Vulhub-DC-3靶机通关攻略
  • 【MySQL】——理解事务的隔离性、MVCC、当前读、快照读