Create knuth_morris_pratt_algorithm.py

This commit is contained in:
Shreyash Kashyap 2023-10-02 10:48:50 +05:30 committed by GitHub
parent e798e5acde
commit 23a99c859d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -0,0 +1,70 @@
# https://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm
def knuth_morris_pratt(text: str, pattern: str) -> list[int]:
"""
Knuth-Morris-Pratt (KMP) string search algorithm in Python.
:param text: The text in which to search for the pattern.
:param pattern: The pattern to search for in the text.
:return: A list of starting positions where the pattern is found in the text.
Examples:
>>> knuth_morris_pratt("ABABDABACDABABCABAB", "ABABCABAB")
[10]
>>> knuth_morris_pratt("ABCABCABCABCABC", "ABC")
[0, 3, 6, 9, 12]
>>> knuth_morris_pratt("AAAAAA", "AA")
[0, 1, 2, 3, 4]
>>> knuth_morris_pratt("ABCDEF", "XYZ")
[]
"""
def build_prefix_table(pattern: str) -> list[int]:
"""
Build the prefix table for the given pattern.
:param pattern: The pattern for which to build the prefix table.
:return: The prefix table, which is a list of integers.
Examples:
>>> build_prefix_table("ABABCA")
[0, 0, 1, 2, 3, 0]
>>> build_prefix_table("ABCABC")
[0, 0, 0, 1, 2, 3]
>>> build_prefix_table("AAAAAA")
[0, 1, 2, 3, 4, 5]
>>> build_prefix_table("XYZ")
[0, 0, 0]
"""
prefix_table = [0] * len(pattern)
j = 0
for i in range(1, len(pattern)):
while j > 0 and pattern[i] != pattern[j]:
j = prefix_table[j - 1]
if pattern[i] == pattern[j]:
j += 1
prefix_table[i] = j
return prefix_table
prefix_table = build_prefix_table(pattern)
positions = []
j = 0
for i in range(len(text)):
while j > 0 and text[i] != pattern[j]:
j = prefix_table[j - 1]
if text[i] == pattern[j]:
j += 1
if j == len(pattern):
positions.append(i - j + 1)
j = prefix_table[j - 1]
return positions
if __name__ == "__main__":
text = input("Enter the text: ")
pattern = input("Enter the pattern to search for: ")
positions = knuth_morris_pratt(text, pattern)
if positions:
print(f"Pattern found at positions: {positions}")
else:
print("Pattern not found in the text.")