From a0d78275d65ea384e887faed07b3ed3ad0422c59 Mon Sep 17 00:00:00 2001 From: Francesco Franco <130352141+Francesco601@users.noreply.github.com> Date: Sun, 7 May 2023 16:29:12 +0200 Subject: [PATCH] added Z algoritm to PR Time and space complexity and other details in comments... --- z_algoritm.py | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 z_algoritm.py diff --git a/z_algoritm.py b/z_algoritm.py new file mode 100644 index 00000000..53191aa7 --- /dev/null +++ b/z_algoritm.py @@ -0,0 +1,81 @@ +# Python program that implements Z algorithm +# for pattern searching from Cormen et al. +# Time complexity O(n + m) where n is length +# of text and m is length of pattern +# Space complexity O(n + m) as well + +# Fills Z array for given string str[] +def getZarr(string, z): + n = len(string) + + # [L,R] make a window which matches + # with prefix of s + l, r, k = 0, 0, 0 + for i in range(1, n): + + # if i>R nothing matches so we will calculate. + # Z[i] using naive way. + if i > r: + l, r = i, i + + # R-L = 0 in starting, so it will start + # checking from 0'th index. For example, + # for "ababab" and i = 1, the value of R + # remains 0 and Z[i] becomes 0. For string + # "aaaaaa" and i = 1, Z[i] and R become 5 + while r < n and string[r - l] == string[r]: + r += 1 + z[i] = r - l + r -= 1 + else: + + # k = i-L so k corresponds to number which + # matches in [L,R] interval. + k = i - l + + # if Z[k] is less than remaining interval + # then Z[i] will be equal to Z[k]. + # For example, str = "ababab", i = 3, R = 5 + # and L = 2 + if z[k] < r - i + 1: + z[i] = z[k] + + # For example str = "aaaaaa" and i = 2, + # R is 5, L is 0 + else: + + # else start from R and check manually + l = i + while r < n and string[r - l] == string[r]: + r += 1 + z[i] = r - l + r -= 1 + +# prints all occurrences of pattern +# in text using Z algo +def search(text, pattern): + + # Create concatenated string "P$T" + concat = pattern + "$" + text + l = len(concat) + + # Construct Z array + z = [0] * l + getZarr(concat, z) + + # now looping through Z array for matching condition + for i in range(l): + + # if Z[i] (matched region) is equal to pattern + # length we got the pattern + if z[i] == len(pattern): + print("Pattern found at index", + i - len(pattern) - 1) + +# Driver Code +if __name__ == "__main__": + text = "run away from run time errors" + pattern = "run" + search(text, pattern) + +