KMP算法(字符串匹配问题)

解决字符串之间匹配的问题。
题目(leetcode 28):在这里插入图片描述

KMP算法是一种空间换时间的算法。它的特点是主串的指针不往回走,利用存储好的信息,避免重复的运算。**在子串那构建一个PMT(Partial Match Table)表。PMT中的值是字符串的前缀集合(除去最后一个元素)与后缀集合(除去第一个元素)的交集中最长元素的长度。(元素集合不包括元素本身)**例如:‘ababa’。前缀集合(‘a’,‘ab’,‘aba’,‘abab’),后缀集合(‘baba’,‘aba’,‘ba’,‘a’),两个集合交集的最长元素为‘aba’,长度为3。说明这个子串从第一个元素开始走和从第三个元素开始走是一样的。(因为元素中有0索引,所以这个子串的表要全部向后移动一位方便计算)

具体做法:
我们要在子串(查询模式字符串中)建立KMP表。这样我们只需要遍历一遍主串即可完成查询。当我们遇到子串和主串字符不匹配的时候,在这个字符前,主串和子串是完全匹配上的,所以我们可以利用KMP的性质(主串的后n个字符和子串中前n个字符是相同的),把子串向前移动n位继续匹配。如图灰色部分就不用继续比较了:
在这里插入图片描述
计算子串的KMP表的时候也可以看成是字符串的匹配过程,即以模式字符串为主字符串,以模式字符串的前缀为目标字符串。一旦字符串匹配成功,那么当前的next值就是匹配成功的字符串的长度。

def strStr(self,t,p):
	if not p:
		return 0
	_next = [0] * len(p)
	def getNext(p,_next):
		#想把KMP的值和子串位置对齐,让它第一位变为没有意义
		_next[0] = -1
		#开始求子串KMP的表,j = -1是为了当子串和主串的字符不相等时,往前走能让i + 1,跳出这个循环
		i = 0
		j = -1
		while i < len(p) -1:
			if j == -1 or p[i] == p[j]:
				i += 1
				j += 1
				_next[i] = j
			else:
				#如果不匹配,就要利用KMP的性质,让子串的位置从头开始走j位,继续判断是否匹配
				j = _next[j]
		getNext(p,_next)
		i = 0
		j = 0
		while i < len(t) and j < len(p):
			#子串KMP表中第一个为-1,所以跟上面一样也是为了跳出循环
			if j == -1 or t[i] == p[j]:
				i += 1
				j += 1
			else:
				j = _next[j]
		if j == len(p):
			#主串上的最后的位置-子串上的长度
			return i - j
		return -1
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值