From 426a185e5036471934052c0b1e35efee94d99bb3 Mon Sep 17 00:00:00 2001 From: Tamandeep Singh Date: Wed, 15 Dec 2021 23:58:21 +0530 Subject: [PATCH 1/3] I have added minimum stack --- .../miscellaneous_data_structures/Minstack.py | 25 +++++++++++++++++++ .../tests/test_stack.py | 14 +++++++---- 2 files changed, 34 insertions(+), 5 deletions(-) create mode 100644 pydatastructs/miscellaneous_data_structures/Minstack.py diff --git a/pydatastructs/miscellaneous_data_structures/Minstack.py b/pydatastructs/miscellaneous_data_structures/Minstack.py new file mode 100644 index 000000000..78e22811c --- /dev/null +++ b/pydatastructs/miscellaneous_data_structures/Minstack.py @@ -0,0 +1,25 @@ +class MinStack(object): + min = float('inf') + + def __init__(self): + self.min = float('inf') + self.stack = [] + + def push(self, x): + if x <= self.min: + self.stack.append(self.min) + self.min = x + self.stack.append(x) + + def pop(self): + t = self.stack[-1] + self.stack.pop() + if self.min == t: + self.min = self.stack[-1] + self.stack.pop() + + def top(self): + return self.stack[-1] + + def getMin(self): + return self.min diff --git a/pydatastructs/miscellaneous_data_structures/tests/test_stack.py b/pydatastructs/miscellaneous_data_structures/tests/test_stack.py index 52756f9cf..6f139b9f6 100644 --- a/pydatastructs/miscellaneous_data_structures/tests/test_stack.py +++ b/pydatastructs/miscellaneous_data_structures/tests/test_stack.py @@ -3,6 +3,7 @@ from pydatastructs.utils.raises_util import raises from pydatastructs.utils.misc_util import _check_type + def test_Stack(): s = Stack(implementation='array') s1 = Stack() @@ -12,6 +13,7 @@ def test_Stack(): assert _check_type(s2, LinkedListStack) is True assert raises(NotImplementedError, lambda: Stack(implementation='')) + def test_ArrayStack(): s = Stack(implementation='array') s.push(1) @@ -23,11 +25,12 @@ def test_ArrayStack(): assert s.pop() == 2 assert s.pop() == 1 assert s.is_empty is True - assert raises(IndexError, lambda : s.pop()) + assert raises(IndexError, lambda: s.pop()) _s = Stack(items=[1, 2, 3]) assert str(_s) == '[1, 2, 3]' assert len(_s) == 3 + def test_LinkedListStack(): s = Stack(implementation='linked_list') s.push(1) @@ -39,16 +42,17 @@ def test_LinkedListStack(): assert s.pop().key == 2 assert s.pop().key == 1 assert s.is_empty is True - assert raises(IndexError, lambda : s.pop()) + assert raises(IndexError, lambda: s.pop()) assert str(s) == '[]' - _s = Stack(implementation='linked_list',items=[1, 2, 3]) + _s = Stack(implementation='linked_list', items=[1, 2, 3]) assert str(_s) == "['(1, None)', '(2, None)', '(3, None)']" assert len(_s) == 3 - s = Stack(implementation='linked_list',items=['a',None,type,{}]) + s = Stack(implementation='linked_list', items=['a', None, type, {}]) assert len(s) == 4 assert s.size == 4 peek = s.peek assert peek.key == s.pop().key - assert raises(TypeError, lambda: Stack(implementation='linked_list', items={0, 1})) + assert raises(TypeError, lambda: Stack( + implementation='linked_list', items={0, 1})) From 7666b6ad0c5bef861ec727cca3a3b68d7640a820 Mon Sep 17 00:00:00 2001 From: Tamandeep Singh Date: Thu, 16 Dec 2021 00:07:27 +0530 Subject: [PATCH 2/3] I have added Minimum Stack --- .../miscellaneous_data_structures/Minstack.py | 25 ------------------- 1 file changed, 25 deletions(-) diff --git a/pydatastructs/miscellaneous_data_structures/Minstack.py b/pydatastructs/miscellaneous_data_structures/Minstack.py index 78e22811c..e69de29bb 100644 --- a/pydatastructs/miscellaneous_data_structures/Minstack.py +++ b/pydatastructs/miscellaneous_data_structures/Minstack.py @@ -1,25 +0,0 @@ -class MinStack(object): - min = float('inf') - - def __init__(self): - self.min = float('inf') - self.stack = [] - - def push(self, x): - if x <= self.min: - self.stack.append(self.min) - self.min = x - self.stack.append(x) - - def pop(self): - t = self.stack[-1] - self.stack.pop() - if self.min == t: - self.min = self.stack[-1] - self.stack.pop() - - def top(self): - return self.stack[-1] - - def getMin(self): - return self.min From 1bdf2d1ce1fa3bd459fd208293d9346b824cc1c4 Mon Sep 17 00:00:00 2001 From: Tamandeep Singh Date: Sat, 18 Dec 2021 02:17:01 +0530 Subject: [PATCH 3/3] I have added Z algorithm for string matching and also a function for returning Z array so that users can use that Z array for other applications like string compression --- pydatastructs/strings/Z_function.py | 93 +++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 pydatastructs/strings/Z_function.py diff --git a/pydatastructs/strings/Z_function.py b/pydatastructs/strings/Z_function.py new file mode 100644 index 000000000..30a23dbe2 --- /dev/null +++ b/pydatastructs/strings/Z_function.py @@ -0,0 +1,93 @@ + +# from pydatastructs.utils.misc_util import ( +# Backend, raise_if_backend_is_not_python) + + +"""Suppose we are given a string s of length n. The Z-function for this string is an array +of length n where the i-th element is equal to the greatest number of characters starting +from the position i that coincide with the first characters of s. + +In other words, z[i] is the length of the longest string that is, at the same time, a +prefix of s and a prefix of the suffix of s starting at i.""" + + +def search(text, pattern): + + # Create concatenated string "P$T" + concat = pattern + "$" + text + l = len(concat) + + # Construct Z array + z = [0] * l + Z_Array(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): + return i - len(pattern) - 1 + + +def Z_Array(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 + + +"""If the programmer only needs the values of Z array for other appllications of this algorithm +such as String compression +""" + + +def Z_function(pattern, text): + concat = pattern + "$" + text + + l = len(concat) + + # Construct Z array + z = [0] * l + Z_Array(concat, z) + return z