Skip to content

Implement prefix function, knuth-morris-pratt another usage #2099

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jun 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions DIRECTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,7 @@
* [Manacher](https://github.com/TheAlgorithms/Python/blob/master/strings/manacher.py)
* [Min Cost String Conversion](https://github.com/TheAlgorithms/Python/blob/master/strings/min_cost_string_conversion.py)
* [Naive String Search](https://github.com/TheAlgorithms/Python/blob/master/strings/naive_string_search.py)
* [Prefix Function](https://github.com/TheAlgorithms/Python/blob/master/strings/prefix_function.py)
* [Rabin Karp](https://github.com/TheAlgorithms/Python/blob/master/strings/rabin_karp.py)
* [Remove Duplicate](https://github.com/TheAlgorithms/Python/blob/master/strings/remove_duplicate.py)
* [Reverse Words](https://github.com/TheAlgorithms/Python/blob/master/strings/reverse_words.py)
Expand Down
65 changes: 65 additions & 0 deletions strings/prefix_function.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
"""
https://cp-algorithms.com/string/prefix-function.html

Prefix function Knuth–Morris–Pratt algorithm

Different algorithm than Knuth-Morris-Pratt pattern finding

E.x. Finding longest prefix which is also suffix

Time Complexity: O(n) - where n is the length of the string
"""


def prefix_function(input_string: str) -> list:
"""
For the given string this function computes value for each index(i),
which represents the longest coincidence of prefix and sufix
for given substring (input_str[0...i])

For the value of the first element the algorithm always returns 0

>>> prefix_function("aabcdaabc")
[0, 1, 0, 0, 0, 1, 2, 3, 4]
>>> prefix_function("asdasdad")
[0, 0, 0, 1, 2, 3, 4, 0]
"""

# list for the result values
prefix_result = [0] * len(input_string)

for i in range(1, len(input_string)):

# use last results for better performance - dynamic programming
j = prefix_result[i - 1]
while j > 0 and input_string[i] != input_string[j]:
j = prefix_result[j - 1]

if input_string[i] == input_string[j]:
j += 1
prefix_result[i] = j

return prefix_result


def longest_prefix(input_str: str) -> int:
"""
Prefix-function use case
Finding longest prefix which is sufix as well

>>> longest_prefix("aabcdaabc")
4
>>> longest_prefix("asdasdad")
4
>>> longest_prefix("abcab")
2
"""

# just returning maximum value of the array gives us answer
return max(prefix_function(input_str))


if __name__ == "__main__":
import doctest

doctest.testmod()