def match_function(raw): """return True if all tags are matched""" S = ArrayStack() # infinite length stack j = raw.find( '<') # string.find, return -1 if not found, return the index if found while j != -1: # while still has < k = raw.find('>', j + 1) # from index >= j+1 find > if k == -1: return False # if not found, the bracket does not match tag = raw[j + 1:k] # does not include < and > if tag[0] == '/': # the close tag if S.is_empty(): return False elif tag[1:] != S.top(): return False else: S.pop() else: S.push( tag ) # push the whole tag into it, since it does not have / sign # continue the loop, find next j >= k+1 j = raw.find('<', k + 1) return S.is_empty( ) # finish the loop, if stack is empty, the html page matches
def reverse_list(data): # modify the list in place if len(data) <= 1: return S = ArrayStack() for each in data: S.push(each) for i in range(len(data)): data[i] = S.pop()
def subset_no_recursion_use_array_queue(data): """ stack to store elements yet to generate subsets, queue store the subsets generated so far. method: quite similar to the recursion method, so the queue dequeue everything and append the same, and the one with new element """ s = ArrayStack() q = ArrayQueue() for each in data: s.push([each]) while not s.is_empty(): new = s.pop() q.enqueue(new) while q.first() != new: out = q.dequeue() q.enqueue(out) q.enqueue(out + new) q.enqueue([]) # manually input the empty set q.show() # or can combine and return as a long list
def no_recursion_use_stack(data): """use stack and without recursion, is quite similar to the code using recursion""" s = ArrayStack() for each in data: s.push(([each], set(data) - set([each]))) while not s.is_empty(): formed_list, remaining_item_set = s.pop() if len(remaining_item_set) == 0: print(formed_list) else: for each in remaining_item_set: formed_list_copy = formed_list[:] formed_list_copy.append(each) s.push((formed_list_copy, remaining_item_set - set([each])))
def reverse_polish_notation(equation): # define all operators and brackets bracket_left = ["(", "[", "{"] bracket_right = [")", "]", "}"] operator = ["+", "-", "*", "/"] # first check if all brackets are matched, using a stack s = ArrayStack() for char in equation: if char in bracket_left: s.push(bracket_left.index(char)) elif char in bracket_right: if s.top() != bracket_right.index(char): raise ValueError("bracket does not match") else: s.pop() else: # for digits and other operation symbol continue if not s.is_empty(): raise ValueError("bracket does not match") """ now do the reverse polish notation: 1. read the input char by char, push into the stack 2. if meet close bracket, pop all elements including the starting bracket 3. then place the operands together, followed by the operator. 4. push the result back to the stack, and continue step 1. 5. when reading finish, pop all elements out and do step 3 again. """ s = ArrayStack() # re-initialize number = "" for char in equation: if char.isnumeric(): number += char elif (char in operator) or (char in bracket_left) or (char in bracket_right): if len(number) != 0: s.push(number) number = "" if char in bracket_right: try: operand2 = s.pop() operator_here = s.pop() operand1 = s.pop() s.pop() # pop the starting bracket s.push(operand1 + operand2 + operator_here) except: raise ValueError("invalid equation {}".foramt(equation)) else: # char in bracket_left or in operator s.push(char) else: raise ValueError("invalid symbol {}".format(char)) # at the end of the loop, check how many left if len(number) != 0: s.push(number) value_left = [s.pop()] while not s.is_empty(): value_left.append(s.pop()) if len(value_left) == 1: return value_left[0] elif len(value_left) == 3: return value_left[2] + value_left[0] + value_left[1] else: raise ValueError("invalid equation {}".format(value_left))
""" transfer(S, T): transfer elements in S to T, the top element in S will be in the bottom of T """ from example_stack import ArrayStack from example_stack import Empty def transfer(S, T): while not S.is_empty(): T.push(S.pop()) if __name__ == '__main__': S = ArrayStack() for i in range(10): S.push(i) S.show() T = ArrayStack() transfer(S, T) print("S") S.show() print("T") T.show()
from example_stack import ArrayStack def transfer(R, S, T): """put everything of S to R, then pop to T""" R_top = R.top() while not S.is_empty(): R.push(S.pop()) while R_top != R.top(): T.push(R.pop()) if __name__ == '__main__': R = ArrayStack() for i in range(1, 3 + 1): R.push(i) S = ArrayStack() S.push(4) S.push(5) T = ArrayStack() for i in range(6, 9 + 1): T.push(i) print("original:") R.show() S.show() T.show()
while not q.is_empty(): if (not find) and (q.first() == target): find = True if not find: index += 1 s.push(q.dequeue()) # does not matter find or not find, need to return s in the original state while not s.is_empty(): q.enqueue(s.pop()) while not q.is_empty(): s.push(q.dequeue()) if find: return index, num-index-1 else: raise ValueError("target {} not in the stack".format(target)) if __name__ == '__main__': s = ArrayStack() values = [2,5,7,9,10,4,1,0] for value in values: s.push(value) s.show() for value in [2, 7, 4]: i1, i2 = find(s, value) print("count from top index = {}, from bottom index = {}".format(i1, i2))
""" same question as q13, but use the deque and a stack """ from example_double_ended_queue import ArrayDoubleEndedQueue from example_stack import ArrayStack D = ArrayDoubleEndedQueue() for i in range(1, 8 + 1): D.add_last(i) S = ArrayStack() print("initially") D.show() S.show() print() for _ in range(3): D.add_last(D.delete_first()) for _ in range(2): S.push(D.delete_first()) for _ in range(2): D.add_last(S.pop()) for _ in range(3): D.add_last(D.delete_first()) print("finally") D.show() S.show()
def _match_function(raw): """function to check the match""" S = ArrayStack() j = raw.find('<') while j != -1: k = raw.find('>', j + 1) if k == -1: return False tag = raw[j + 1:k] if tag[0] == '/': # this is a close tag if S.is_empty(): return False elif tag[1:] != S.top(): return False else: S.pop() else: # this is a starting tag space_index = tag.find(" ") if space_index == -1: S.push(tag) else: S.push(tag[:space_index]) # finish this part, continue the loop j = raw.find("<", k + 1) # the loop ends, the stack should be empty return S.is_empty()
def __init__(self): self._a = ArrayStack() self._b = ArrayStack() self._num = 0 self._reverse_flag = True # True means the first element is at the bottom of the stack
class ArrayQueueUseTwoStacks: """ use two stacks to demonstrate a queue, "show" is not included in the task for simplicity. """ def __init__(self): self._a = ArrayStack() self._b = ArrayStack() self._num = 0 self._reverse_flag = True # True means the first element is at the bottom of the stack def __len__(self): return self._num def is_empty(self): return self._num == 0 def first(self): if self._num == 0: raise Empty("queue is empty") else: if self._reverse_flag: # the first element is at the bottom of the stack # move everything of stack a to stack b, return the top while not self._a.is_empty(): self._b.push(self._a.pop()) # swap two stacks self._a, self._b = self._b, self._a self._reverse_flag = False else: # the first element is at the top of stack a self._reverse_flag = True return self._a.top() def enqueue(self, value): # put a value into the stack, using push self._num += 1 if self._reverse_flag: # if the first element is at the bottom of stack a self._a.push(value) else: # the first element is at the top of stack a # need to push to b first, then move everything from a to b self._b.push(value) while not self._a.is_empty(): self._b.push(self._a.pop()) # swap two stacks self._a, self._b = self._b, self._a def dequeue(self): # return the first value if self._num == 0: raise Empty("queue is empty") else: self._num -= 1 if self._reverse_flag: # the first element is at the bottom of stack a: # move to b, then pop, remember to swap and change the flag while not self.is_empty(): self._b.push(self._a.pop()) value = self._b.pop() self._a, self._b = self._b, self._a self._reverse_flag = False return value else: return self._a.pop()
class ArrayQueueUseTwoStacks_2: """ a better design. enqueue: O(n), and then make the first element at the top of the queue. dequeue and first: O(1) """ def __init__(self): self._a = ArrayStack() self._b = ArrayStack() self._num = 0 def __len__(self): return self._num def is_empty(self): return self._num == 0 def first(self): return self._a.top() def enqueue(self, value): # put the new element at the bottom of the stack # note that right now self._a has first element at the top of the stack self._num += 1 while not self._a.is_empty(): self._b.push(self._a.pop()) self._b.push(value) # this is the new value while not self._b.is_empty(): self._a.push(self._b.pop()) def dequeue(self): # return the first value if self._num == 0: raise Empty("queue is empty") else: self._num -= 1 return self._a.pop()
def __init__(self): self._a = ArrayStack() self._b = ArrayStack() self._num = 0