一、KMP算法学习:
1.目的:解决字符串匹配问题
2.主要思想:当出现字符串不匹配时,利用已经匹配过的信息避免从头再去做匹配。
3.next数组:存储每个对应位置之前的公共前后缀数量的数组。
编号 | 0 | 1 | 2 | 3 | 4 | 5 |
字符串 | a | a | b | a | a | f |
next数组 | 0 | 1 | 0 | 1 | 2 | 0 |
4.代码实现next数组:
def getnext(next,s):
j = 0
next[0] = 0
for i in range(1,len(s)):
while j>0 and s[i] != s[j]:
j = next[j-1]
if s[i]==s[j]:
j += 1
next[i] = j
return next
二、刷题:
1.leetcode题目28 找出字符串中第一个匹配的下标(easy):
题目描述:
给你两个字符串 haystack
和 needle
,请你在 haystack
字符串中找出 needle
字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle
不是 haystack
的一部分,则返回 -1
。
解决:
①暴力匹配:
class Solution:
def strStr(self, haystack: str, needle: str) -> int:
for i in range(0,len(haystack)- len(needle) + 1):
if haystack[i:i+len(needle)] == needle:
return i
return -1
②KMP算法:
class Solution:
def getNext(self,next1,s):
next1[0] = 0
j = 0
for i in range(1,len(s)):
while j >0 and s[i]!=s[j]:
j = next1[j-1]
if s[i] == s[j]:
j += 1
next1[i] = j
return next1
def strStr(self, haystack: str, needle: str) -> int:
if len(needle) == 0:
return 0
m = len(haystack)
n = len(needle)
if n>m:
return -1
next1 = [0]*n
j = 0
next_new = self.getNext(next1,needle)
for i in range(m):
while j>0 and haystack[i]!=needle[j]:
j = next_new[j-1]
if haystack[i] == needle[j]:
j += 1
if j==n:
return i-n+1
return -1
2.leetcode题目 459 重复的子字符串(easy):
题目描述:
给定一个非空的字符串 s
,检查是否可以通过由它的一个子串重复多次构成。
解决:
①暴力法:
class Solution:
def repeatedSubstringPattern(self, s: str) -> bool:
n = len(s)
for i in range(1,n//2 + 1):
if n%i==0:
if all(s[j] == s[j-i] for j in range(i,n)):
return True
return False
②KMP算法:
class Solution:
def getNext(self,next1,s):
j = 0
next1[0] = 0
for i in range(1,len(s)):
while j>0 and s[i]!=s[j]:
j = next1[j-1]
if s[i]==s[j]:
j += 1
next1[i] = j
return next1
def repeatedSubstringPattern(self, s: str) -> bool:
l = len(s)
next1 = [0]*l
next_new = self.getNext(next1,s)
if next_new[-1]!=0 and l%(l-next_new[-1]) == 0:
return True
else:
return False