Stack and queue idea

Posted by Sobbs on Wed, 22 Sep 2021 03:33:18 +0200

1. Use the stack idea to judge whether a given string of parentheses match left and right.

Idea: if the character is a left bracket, it is stored in the stack. If it is a right bracket, judge whether the bracket at the top of the stack matches it. If it matches, it pops up. If it does not match or the stack is not empty after traversing the bracket string, it indicates that the bracket string does not match left and right.

def bracket_match(str_s):
    if not str_s:
        return None
    dict_match = {'(':')','[':']','{':'}'}
    bracket = []
    for ch in str_s:
        if ch in dict_match:
            bracket.append(ch)
        else:
            if dict_match[bracket[-1]] == ch:
                bracket.pop()
            else:
                return False
    if not bracket:
        return True
    else:
        return False

str_s = input("Please input a brackets string:")
print(bracket_match(str_s))

2. Using stack to solve maze problem (depth first traversal, also known as backtracking method):

Given a matrix composed of 0 and 1, and given the coordinates of the starting point and the end point, 1 in the matrix represents that it is impossible to pass, so find the path from the starting point to the end point.

Idea: store the starting point in the stack and check whether the four directions of the starting point position are feasible according to the order of up, down, left and right. If feasible, store the coordinates of the position in the stack and continue to check whether the four directions of the position are feasible. If all four directions of one location are impassable, go back to the previous location and continue to find out whether other directions are feasible. To sum up, one sentence is: when a road goes to black, don't hit the south wall and don't look back. After hitting the south wall, go back to the previous position and continue to find a way to black.

maze = [
    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    [1, 0, 0, 1, 0, 0, 0, 1, 0, 1],
    [1, 0, 0, 1, 0, 0, 0, 1, 0, 1],
    [1, 0, 0, 0, 0, 1, 1, 0, 0, 1],
    [1, 0, 1, 1, 1, 0, 0, 0, 0, 1],
    [1, 0, 0, 0, 1, 0, 0, 0, 0, 1],
    [1, 0, 1, 0, 0, 0, 1, 0, 0, 1],
    [1, 0, 1, 1, 1, 0, 1, 1, 0, 1],
    [1, 1, 0, 0, 0, 0, 0, 0, 0, 1],
    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
]

direction = [
    lambda x,y: (x,y-1),
    lambda x,y: (x+1,y),
    lambda x,y: (x,y+1),
    lambda x,y: (x-1,y)
]

def maze_path_depth(x1,y1,x2,y2):
    stack_path = [(x1,y1)]
    while stack_path:
        if stack_path[-1][0] == x2 and stack_path[-1][1] == y2:     # If an exit is found, the output path
            for pos in stack_path:
                print(pos, end=" ")
            return
        for dir in direction:       # Find out if four directions are feasible
            next_pos = dir(stack_path[-1][0],stack_path[-1][1])
            if maze[next_pos[0]][next_pos[1]] == 0:
                stack_path.append(next_pos)
                maze[next_pos[0]][next_pos[1]] = -1         # The passing position shall be changed to - 1 to prevent passing again
                break
        else:
            maze[next_pos[0]][next_pos[1]] = -1
            stack_path.pop()        # If all four directions are impassable, go back to the previous position coordinate
    else:
        return None

maze_path_depth(1,1,8,8)

3. Use queue to solve maze problem (breadth first traversal):

Idea: store the starting point in the queue, then find out whether the four directions are feasible, and store all feasible positions in the queue. Take the position from the head of the team next time, and then store the feasible positions in the four directions of the position into the queue. This ensures that the shortest path from the start point to the end point is found.

In order to reconstruct the shortest path, in addition to the coordinates after the position, the num value is added to indicate where the position comes from.

maze = [
    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    [1, 0, 0, 1, 0, 0, 0, 1, 0, 1],
    [1, 0, 0, 1, 0, 0, 0, 1, 0, 1],
    [1, 0, 0, 0, 0, 1, 1, 0, 0, 1],
    [1, 0, 1, 1, 1, 0, 0, 0, 0, 1],
    [1, 0, 0, 0, 1, 0, 0, 0, 0, 1],
    [1, 0, 1, 0, 0, 0, 1, 0, 0, 1],
    [1, 0, 1, 1, 1, 0, 1, 1, 0, 1],
    [1, 1, 0, 0, 0, 0, 0, 0, 0, 1],
    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
]

direction = [
    lambda x,y: (x-1,y),
    lambda x,y: (x,y+1),
    lambda x,y: (x+1,y),
    lambda x,y: (x,y-1)
]

def maze_path_extend(x1,y1,x2,y2):
    stack_path = [(x1,y1,-1)]       # The third element indicates that the current position comes from the position represented by the first few elements in the path
    path = []       # Because stack_path needs pop every time, so path is used to store the passing location
    num = -1        # Used to indicate that the current position is from the position represented by the num element in the path.
    maze[x1][y1] = -1
    while stack_path:
        cur_pos = stack_path.pop(0)
        path.append(cur_pos)        # Store the passed location every time
        num += 1
        if cur_pos[0] == x2 and cur_pos[1] == y2:
            real_path = []
            while cur_pos[2] != -1:     # When num = -1, it means that it has been traced back to the starting point
                real_path.append((cur_pos[0],cur_pos[1]))
                cur_pos = path[cur_pos[2]]      # According to the value of num, find out where the position comes from
            real_path.append((cur_pos[0], cur_pos[1]))      # Stores the path from the start point to the end point
            real_path.reverse()
            for pos in real_path:
                print(pos,end=' ')
            return True
        for dir in direction:       # Find out if four directions are feasible
            next_pos = dir(cur_pos[0],cur_pos[1])
            if maze[next_pos[0]][next_pos[1]] == 0:
                stack_path.append((next_pos[0],next_pos[1],num))
                maze[next_pos[0]][next_pos[1]] = -1         # The passing position shall be changed to - 1 to prevent passing again
    else:
        return None

if __name__ == '__main__':
    print(maze_path_extend(1,1,8,8))

Topics: Python Algorithm