字符串匹配KMP算法的基本原理及python实现_Cris_Lee卡卡卡的博客-程序员宅基地

技术标签: python  算法基础  字符串匹配  KMP  

KMP算法是字符串匹配问题中非常经典的算法。最近查找了很多相关资料,直到看到下面这两篇博客,终于理解了KMP的基本原理。
KMP算法的核心即是计算字符串M每一个位置之前的字符串的前缀和后缀公共部分的最大长度。获得M每一个位置的最大公共长度之后,就可以利用该最大公共长度快速和字符串S比较。当每次比较到两个字符串的字符不同时,我们就可以根据最大公共长度将字符串M向右移动,接着继续比较下一个位置。
强烈推荐大家看一看以下两篇博客,相信能有所收获。
首先推荐看这篇,篇幅较短,没有大量的算法细节,建议先读这篇,对KMP算法的核心思想有所把握:
http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html
在了解基本思想后,建议详细阅读下面这位大神的博客,写的非常清晰,认真研读之后,相信会对KMP有深入的了解,并能编程实现。
https://blog.csdn.net/v_july_v/article/details/7041827
在网上没有查到比较清晰的python解决方案,在这里给出python实现方法,
供参考。(笔者测试了多个测试用例,均通过,如有问题,欢迎指出~)

问题:

搜索字符串S中是否含有模式串P,如果有,返回True,否则返回False

基于python2实现:

def KMP(S,P):
	def next_list_generate(s):
		'''
		产生模式串的next列表,此处为KMP核心部分,强烈建议大家仔细阅读     上面的两篇博客
		'''
		if len(s) == 0 :
			return False
		if len(s) == 1:
			return [-1]
		if len(s) == 2:
			return [-1,0]
		next_list = [0]*len(s)
		next_list[0]= -1
		flag = 2
		k = 0
		while flag < len(s):
			if k == -1 or s[k]==s[flag-1]:
				k    += 1
				next_list[flag] = k
				flag += 1
			else:
				k = next_list[k]
		return next_list
	if len(S)<len(P):
		return False
	next_list = next_list_generate(P)
	match = 0
	flag  = 0
	while flag+len(P)<=len(S) :
		for i in range(len(P)):
			if P[i] == S[flag+i]:
				match += 1
			else:
				flag += match - next_list[i]
				break
		if match == len(P):
			return True
		match = 0
	return False

测试样例:

#instance1
Str = 'freerh'
Pattern = 'erh'
print KMP(Str,Pattern)
#instance2
Str = 'abcd'
Pattern = 'be'
print KMP(Str,Pattern)
#instance3
Str = 'abcdf'
Pattern = 'bcdg'
print KMP(Str,Pattern)

测试输出:

True
False
False

基于python3(python3.8)实现(2020.12.16新增)

def KMP_search(text:str,pattern:str)->bool:
	if len(pattern)>len(text) or len(pattern)==0:
		return False
	def get_next(pattern):
		next_list=[0 for i in range(len(pattern))]
		next_list[0]=-1
		i=-1
		j=0
		while(j<len(pattern)-1):
			if(i==-1 or pattern[i]==pattern[j]):
				i+=1
				j+=1
				next_list[j]=i
			else:
				i=next_list[i]
		return next_list
	next_list=get_next(pattern)
	ti=0
	pi=0
	while ti<len(text):
		if text[ti]==pattern[pi]:
			if pi==len(pattern)-1:
				return True
			else:
				ti+=1
				pi+=1
		elif pi==0:
			ti+=1
		else:
			pi=next_list[pi]
	return False

测试输入:

print(KMP_search('b','b'))
print(KMP_search('bsdfss','bsdfss'))
print(KMP_search('bsdfsa','sa'))
print(KMP_search('b','a'))
print(KMP_search('bsdfsa','ssa'))
print(KMP_search('bsdfsa','bsdfsb'))

测试输出:

True
True
True
False
False
False
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/lrs1353281004/article/details/82633619

智能推荐

su cannot set user id Resource temporarily unavailable故障解决-程序员宅基地

大家好!今天和大家分享一个case,现象是这样的,centos6 当我用su - oracle时发生错误提示:su cannot set user id Resource temporarily unavaila...

shell 函数参数为数组传递-程序员宅基地

You cannot pass an array, you can only pass its elements (i.e. the expanded array).#! /bin/bashfunction f() { a=("$@") ((last_idx=${#a[@]} - 1)) b=${a[last_idx]} unset a[last_idx]

关于昆仑通态通道处理设置_mcgs通道处理-程序员宅基地

网上找过来的,亲测有用,收藏下!!!只要数据长度不超过8位(纯数字的长度,如1234567.8、123456.78)的小数问题都是可以解决的,设置小数共有2个地方需要注意:一、首先是设备窗口中1.设备窗口,双击打开驱动,对于需要做通道处理的通道,双击对应的通道处理列,如下图的VW0。 2.以VW0为例,双击上图红色区域,会出现“通道处理设置”窗口,双击右边“处理内容”红框部分,..._mcgs通道处理

android如何编写service,如何编写android service.doc_金门走狗的博客-程序员宅基地

如何编写android service.doc下载提示(请认真阅读)1.请仔细阅读文档,确保文档完整性,对于不预览、不比对内容而直接下载带来的问题本站不予受理。2.下载的文档,不会出现我们的网址水印。3、该文档所得收入(下载+内容+预览)归上传者、原创作者;如果您是本文档原作者,请点此认领!既往收益都归您。文档包含非法信息?点此举报后获取现金奖励!下载文档到电脑,查找使用更方便20积分还剩页未读,..._android写一个service

数学建模中各种评价类模型的优点和缺点总结_熵值法的优缺点-程序员宅基地

数学建模中,评价类模型是一类比较基础的数学模型之一,往往是对应生活中的一些实际问题。最常见的数学模型包括:层次分析法、模糊综合评价、熵值法、TOPSIS法、数据包络分析、秩和比法、灰色关联法。......_熵值法的优缺点

React & Ant-Design 应用 —— Form.item 的 name和rules;为什么设置required不显示_Silam Lin的博客-程序员宅基地

React & Ant-Design组件之 Form.item的name和rulesForm.item的使用Form.item的使用导入:import React from 'react';import ReactDOM from 'react-dom';import { Form } from 'antd';return ( <Form.item label='userName' name="userName", rules={[required:true]}

随便推点

NET中高级开发工程师面试题(二)_net高级软件工程师面试题-程序员宅基地

1、Redis 和 MemCache 的区别性能:redis 只能使用单核,而 Memcache 可以使用多核,所以在比较上,平均每一个核上Redis在存储小数据时比Memcached性能更高。而在100k以上的数据中,Memcache性能要高于Redis,虽然Redis最近也在存储大数据的性能上进行优化,但是比起Memcache,还是稍有逊色。说了这么多,结论是,无论你使用哪一个,每秒处..._net高级软件工程师面试题

iOS9适配问题-程序员宅基地

iOS9适配问题最近升级到XCode7之后发现工程需要针对iOS9做一些适配,如下几点是我项目中遇到的适配问题,仅供大家参考如有问题欢迎加Q群157672725讨论:网络适配ATS问题Bitcode导致的编译问题网络适配ATS问题App Transport Security(ATS)是Apple为提高系统及应用安全性而在iOS 9和OS X EI Capitan中引入的新特性。一旦开启ATS后

用python实现一行代码做一个自己的动态二维码-程序员宅基地

效果图本次来教大家如何做一个动态的二维码,让自己的二维码有个性起来~准备工作pip install MyQR参数介绍words:扫描二维码后展示的内容,可以是网页链接,也可以是文字描述veision:生成二维码的边长,范围是1至40,数字越大边长越大level:二维码纠错级别,范围为[‘L’,‘M’,‘Q’,‘H’],H为最高级默认选项。picture:自定义二维码背景图,支持格式为 .jpg,.png,.bmp,.gifcolorized:二维码背景颜色,默认为 False,即黑白色,

error LNK2019: 无法解析的外部符号 “public: void __thiscall-程序员宅基地

这个问题出现的大部分原因,以下连接的博客讲的很明确https://blog.csdn.net/u013321328/article/details/79628494但我下面将的这个原因特别玄学,这个问题一般出现时会有一个提示:“LNK4042: 对象被多次指定;已忽略多余的指定”此问题一般是由于将release模式切换成debug模式后出现的,这个问题是由于“使用原有工程时,直接在工程里将.cpp文件重命名为.h文件,.vcxproj文件中的属性并没有改变而导致。”解决方案,将重命名的.h文

H3C开启Ssh-程序员宅基地

[H3C]ssh server enable //开启SSH服务[H3C]user-interface vty 0 4[H3C-ui-vty0-4]authentication-mode password //认证模式选择为password,ssh不支持[H3C-ui-vty0-4]protocol inbound ssh //..._protocol inbound ssh

ecu故障现象_车辆显示ECU故障是什么原因如何处理?-程序员宅基地

查看电路,接头处是否虚接,再一个就是电动车都有一个ECU,就是电脑,有可能是电脑出了问题。“ECU”就是指电动车的控制器。是用来控制电动车电机的启动、运行、进退、速度、停止以及电动车的其它电子器件的核心控制器件。它就象是电动车的大脑,是电动车上重要的部件。主要控制电机的转速,同时兼有多种保护功能,如欠压保护、限流保护、刹车断电等。电动车控制器的常见故障:一、电动车骑行噪音大带负荷速度变慢,车子停稳...

推荐文章

热门文章

相关标签