1 from typing import List
2
3
4 class KMP:
5 def _next(self, pattern: str) -> List[int]:
6 """
7 计算next数组
8 """
9 next = [-1] * len(pattern)
10 i, j = -1, 0
11 while j < len(pattern) - 1:
12 if i == -1 or pattern[i] == pattern[j]:
13 i += 1
14 j += 1
15 next[j] = i if pattern[i] != pattern[j] else next[i] # 这里相对朴素方法已经有了优化
16 else:
17 i = next[i]
18 return next
19
20 def match(self, string: str, pattern: str) -> int:
21 """
22 返回第一个匹配位置,失败返回len(string)
23 """
24 next = self._next(pattern)
25 i, j = 0, 0
26 while i < len(string) and j < len(pattern):
27 if j == -1:
28 i += 1
29 j += 1
30 elif string[i] == pattern[j]:
31 i += 1
32 j += 1
33 else:
34 j = next[j]
35 return i - j if j == len(pattern) else i