Example #1
0
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
Example #2
0
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()
Example #3
0
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
Example #4
0
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])))
Example #5
0
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))
Example #6
0
"""
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()
Example #7
0
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()
Example #8
0
    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))
Example #9
0
"""
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()
Example #10
0
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()
Example #11
0
 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
Example #12
0
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()
Example #13
0
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()
Example #14
0
 def __init__(self):
     self._a = ArrayStack()
     self._b = ArrayStack()
     self._num = 0