You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
37 lines
1.2 KiB
37 lines
1.2 KiB
from typing import Dict
|
|
|
|
|
|
def make_km_table(pattern: str) -> Dict[str, int]:
|
|
PATTERN_LENGTH = len(pattern)
|
|
table = {}
|
|
for index_from_left, char in enumerate(pattern[:-1]):
|
|
table[char] = PATTERN_LENGTH - index_from_left - 1
|
|
return table
|
|
|
|
|
|
class Bm(object):
|
|
def __init__(self, text: str, pattern: str):
|
|
self.text = text
|
|
self.pattern = pattern
|
|
self.table = make_km_table(pattern)
|
|
|
|
def decide_slide_width(self, c: str) -> int:
|
|
try:
|
|
return self.table[c]
|
|
except KeyError:
|
|
return len(self.pattern)
|
|
|
|
def search(self) -> int:
|
|
PATTERN_LENGTH = len(self.pattern)
|
|
head = PATTERN_LENGTH - 1
|
|
while head < len(self.text):
|
|
if self.text[head] == self.pattern[-1]:
|
|
for index_from_right, char in enumerate(reversed(self.pattern)):
|
|
if self.text[head - index_from_right] != char:
|
|
head += self.decide_slide_width(self.text[head])
|
|
break
|
|
else:
|
|
return head - PATTERN_LENGTH + 1
|
|
else:
|
|
head += self.decide_slide_width(self.text[head])
|
|
return -1
|