栈的实现以及使用实例 python

一、一种实现

该种实现方式的性能更好

        假设列表的尾部是栈的顶端。当栈增长时(即进行 push 操作), 新的元素会被添加到列表的尾部。pop 操作同样会修改这一端。

# main.py
class Stack:
    def __init__(self):
        self.items = []

    def isEmpty(self):
        return self.items == []

    def push(self, item):
        self.items.append(item)

    def pop(self):
        return self.items.pop()

    def peek(self):
        return self.items[len(self.items) - 1]

    def size(self):
        return len(self.items)


s = Stack()
print(s.isEmpty())

# 由于push函数只向栈中添加元素,而没有返回值,所以输出只有参数的地址
s.push(8.4)
print(s)

二、第二种实现

        选择列表的头部作为栈的顶端。不过在这种情况下,便无法直接使 用 pop 方法和 append 方法,而必须要用 pop 方法和 insert 方法显式地访问下标为 0 的元素, 即列表中的第 1 个元素。

class Stack:
    def __init__(self):
        self.items = []

    def isEmpty(self):
        return self.items == []

    def push(self, item):
        self.items.insert(0,item)

    def pop(self):
        return self.items.pop(0)

    def peek(self):
        return self.items[0]

    def size(self):
        return len(self.items)

三、匹配括号通过第一种实现

思路:由一个空栈开始,从左 往右依次处理括号。如果遇到左括号,便通过 push 操作将其加入栈中,以此表示稍后需要有一 个与之匹配的右括号。反之,如果遇到右括号,就调用 pop 操作。只要栈中的所有左括号都能 遇到与之匹配的右括号,那么整个括号串就是匹配的;如果栈中有任何一个左括号找不到与之匹 配的右括号,则括号串就是不匹配的。在处理完匹配的括号串之后,栈应该是空的。

#因为Stack类的定义在main.py,所以需要先导入
from main import Stack


def parChecker(symbolString):
    s = Stack()
    balanced = True
    index = 0
    while index < len(symbolString) and balanced:
        symbol = symbolString[index]
        if symbol == "(":
            s.push(symbol)
        elif symbol == ")":
            if s.isEmpty():
                balanced = False
            else:
                s.pop()

        index += 1

    if balanced and s.isEmpty():
        return True
    else:
        return False

四、匹配符号

思路:每一个左符号都将被压 入栈中,以待之后出现对应的右符号。唯一的区别在于,当出现右符号时,必须检测其类型是否 与栈顶的左符号类型相匹配。如果两个符号不匹配,那么整个符号串也就不匹配。同样,如果整 个符号串处理完成并且栈是空的,那么就说明所有符号正确匹配

#Stack类定义在main.py中,使用时需要导入
from main import Stack


def parChecker(symbolString):
    s = Stack()
    balanced = True
    index = 0
    while index < len(symbolString) and balanced:
        symbol = symbolString[index]
        if symbol in "([{":
            s.push(symbol)
        elif symbol == ")":
            if s.isEmpty():
                balanced = False
            else:
                top = s.pop()
                if not matches(top,symbol):
                    balanced = False

        index += 1

    if balanced and s.isEmpty():
        return True
    else:
        return False

def matches(open,close):
    opens = "([{"
    closers = ")]}"

    return opens.index(open) == closers.index[close]

五、进制转换

1.十进制转换成二进制

from main import Stack


def divideBy2(decNumber):
    remstack = Stack()

    while decNumber > 0:
        rem = decNumber % 2
        remstack.push(rem)
        decNumber = decNumber // 2

    binString = ""
    while not remstack.isEmpty():
        binString = binString + str(remstack.pop())#强制类型转换

    return binString

print(divideBy2(32))

2.将十进制转换成任意进制

思路:

        可以将 divideBy2 函数修改成接受一个十进制数以及希望转换的进制基数,“除以 2”则变 成“除以基数”;有时余数会超过10,需要定义一个字符串。

        一种解决方法是添加一些字母字符到数字中。例如,十六进制使用 10 个数字以及前 6 个字 母来代表 16 位数字。

from main import Stack


def baseConverter(decNumber, base):
    digits = "0123456789ABCDEF"

    remstack = Stack()

    while decNumber > 0:
        rem = decNumber % base
        remstack.push(rem)
        decNumber = decNumber // base

    newString = ""
    while not remstack.isEmpty():
        newString = newString + digits(remstack.pop())#字符拼接+digits(索引)

    return newString

六中序表达式转换成后序表达式或者前序表达式

1.转换成后序表达式

思路:

(1) 创建用于保存运算符的空栈 opstack,以及一个用于保存结果的空列表。

(2) 使用字符串方法 split 将输入的中序表达式转换成一个列表。

(3) 从左往右扫描这个标记列表。

 如果标记是操作数,将其添加到结果列表的末尾。

 如果标记是左括号,将其压入 opstack 栈中。

 如果标记是右括号,反复从 opstack 栈中移除元素,直到移除对应的左括号。将从栈中 取出的每一个运算符都添加到结果列表的末尾。

 如果标记是运算符,将其压入 opstack 栈中。但是,在这之前,需要先从栈中取出优先 级更高或相同的运算符,并将它们添加到结果列表的末尾。

(4) 当处理完输入表达式以后,检查 opstack。将其中所有残留的运算符全部添加到结果列 表的末尾

from main import Stack
import string


def infixToPostfix(infixexper):
    '''
    中序表达式到后序表达式的转换
    :param infixexper:
    :return:
    '''
    # 给运算符定义优先级
    prec = {}
    prec["*"] = 3
    prec["/"] = 3
    prec["+"] = 2
    prec["-"] = 2
    prec["("] = 1

    opStack = Stack()  # 保存运算符的空栈
    postfixList = []  # 保存结果的空列表

    tokenList = infixexper.split()

    for token in tokenList:
        if token in string.ascii_uppercase:#什么意思
            postfixList.append(token)
        elif token == '(':
            opStack.push(token)
        elif token == ')':
            topToken = opStack.pop()
            while topToken != '(':
                postfixList.append(topToken)
                topToken = opStack.pop()
        else:
            while (not opStack.isEmpty()) and (prec[opStack.peek()] >= prec[token]):
                postfixList.append(opStack.pop())
            opStack.push(token)

    while not opStack.isEmpty():
        postfixList.append(opStack.pop())

    return " ".join(postfixList)


infixexpr = "( A + B ) * ( C + D )"
print(infixToPostfix(infixexpr))

2.计算后序表达式

from main import Stack
def postfixEval(postfixExpr):
    operandStack = Stack()

    #从左向右遍历,如果为操作数则存入栈中,如果是运算符则取出栈中的两个运算数进行计算,结果存入栈中
    tokenList = postfixExpr.split()#转化为列表

    for token in tokenList:
        #遍历到运算数
        if token in "0123456789":
            operandStack.push(int(token))#列表中的数据是字符型
        #遍历到运算符
        else:
            operandr = operandStack.pop()#中序右运算数
            operandl = operandStack.pop()#中序左运算数
            result = domath(token,operandl,operandr)
            operandStack.push(result)

    return operandStack.pop()

def domath(token,operandl,operandr):
    '''
    定义运算
    :param token: 运算符
    :param operandl: 运算数
    :param operandr: 运算数
    :return: 运算结果
    '''
    if token == "*":
        result = operandl*operandr
    elif token == "/":
        result = operandl / operandr
    elif token == "+":
        result = operandl + operandr
    elif token == "-":
        result = operandl - operandr
    else:
        #如果不是定义的,输出此,但是会多输出一个数字
        print("the operator does not define the operation")#运算符未定义运算
        return 0

    return result

print(postfixEval("4 5 6 ^ +"))


  • 19
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
求解算法? 可以使用深度优先搜索算法(DFS)来求解迷宫。具体实现方法是使用来保存走过的路径,当搜索到终点时,中的路径就是一条正确的路径。以下是 Python 实现迷宫求解的示例代码: ```python # 定义迷宫 maze = [[0, 0, 0, 0, 0, 0, 0, 0], [0, 1, 1, 0, 1, 1, 1, 0], [0, 1, 0, 0, 0, 1, 0, 0], [0, 1, 1, 1, 1, 1, 0, 1], [0, 1, 0, 0, 0, 1, 0, 0], [0, 1, 1, 0, 1, 1, 1, 0], [0, 0, 0, 0, 0, 0, 0, 0]] # 定义节点 class StackNode: def __init__(self, x, y, next=None): self.x = x self.y = y self.next = next # 定义 class Stack: def __init__(self): self.head = None def push(self, x, y): node = StackNode(x, y, self.head) self.head = node def pop(self): if self.head is None: return None node = self.head self.head = node.next return node def is_empty(self): return self.head is None # 定义迷宫求解函数 def solve_maze(maze): start_x, start_y = 1, 1 # 起点 end_x, end_y = 5, 6 # 终点 stack = Stack() stack.push(start_x, start_y) directions = [(0, 1), (1, 0), (0, -1), (-1, 0)] # 右下左上 while not stack.is_empty(): node = stack.pop() x, y = node.x, node.y for dx, dy in directions: nx, ny = x + dx, y + dy if maze[nx][ny] == 0: # 未走过的路径 stack.push(nx, ny) maze[nx][ny] = maze[x][y] + 1 # 记录步数 if nx == end_x and ny == end_y: # 到达终点 return maze[nx][ny] return None # 没有找到正确路径 # 输出迷宫求解结果 steps = solve_maze(maze) if steps is None: print("没有找到正确路径") else: print(steps) ``` 这段代码中,我们首先定义了一个迷宫,使用 0 表示通路,使用 1 表示墙,然后定义了一个节点和一个数据结构,节点保存迷宫中的一个位置,用于保存路径。在迷宫求解函数中,我们首先将起点入,然后使用深度优先搜索算法不断向前寻找可走的路径,直到找到终点或者为空时停止。当搜索到一个节点时,我们将其未走过的路径入,并记录到达该节点时的步数。如果最终能够到达终点,则返回到达终点的步数。如果没有找到正确的路径,则返回 None。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值