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

  1. from typing import Dict
  2. def make_km_table(pattern: str) -> Dict[str, int]:
  3. PATTERN_LENGTH = len(pattern)
  4. table = {}
  5. for index_from_left, char in enumerate(pattern[:-1]):
  6. table[char] = PATTERN_LENGTH - index_from_left - 1
  7. return table
  8. class Bm(object):
  9. def __init__(self, text: str, pattern: str):
  10. self.text = text
  11. self.pattern = pattern
  12. self.table = make_km_table(pattern)
  13. def decide_slide_width(self, c: str) -> int:
  14. try:
  15. return self.table[c]
  16. except KeyError:
  17. return len(self.pattern)
  18. def search(self) -> int:
  19. PATTERN_LENGTH = len(self.pattern)
  20. head = PATTERN_LENGTH - 1
  21. while head < len(self.text):
  22. if self.text[head] == self.pattern[-1]:
  23. for index_from_right, char in enumerate(reversed(self.pattern)):
  24. if self.text[head - index_from_right] != char:
  25. head += self.decide_slide_width(self.text[head])
  26. break
  27. else:
  28. return head - PATTERN_LENGTH + 1
  29. else:
  30. head += self.decide_slide_width(self.text[head])
  31. return -1