python 栈、用栈实现综合计算器

栈的基本介绍

出栈(pop)示意图

入栈(push)示意图 

栈的应用场景

数组模拟栈

思路分析 

 代码实现

# 用数组模拟栈
class ArrayStack:
    def __init__(self, size):
        self.max_size = size  # 栈的最大容量
        self.top = -1  # top 表示栈顶
        self.stack = []  # 用列表表示数组

    # 判断栈满
    def is_full(self):
        return self.top == self.max_size - 1

    # 判断栈空
    def is_empty(self):
        return self.top == -1

    # 入栈
    def push(self, ele: int):
        if self.is_full():
            print("栈已满")
        else:
            self.top += 1
            self.stack.insert(self.top, ele)

    # 出栈
    def pop(self) -> int:
        if self.is_empty():
            print("栈空")
        else:
            val = self.stack.pop(self.top)
            self.top -= 1
            return val

    # 获取栈顶元素
    def get_top(self):
        if self.is_empty():
            return
        return self.stack[self.top]

    # 遍历栈,从栈顶开始
    def for_stack(self):
        if self.is_empty():
            print("栈空")
            return
        print("栈元素:", end="")
        i = self.top
        while i >= 0:
            print(self.stack[i], end="  ")
            i -= 1
        print()

# 测试
def test_array_stack(size):
    stack = ArrayStack(size)
    while True:
        print("=====栈的操作菜单=====")
        print("1、入栈")
        print("2、出栈")
        print("3、显示栈")
        print("4、退出")
        try:
            select = int(input("请选择:"))
        except Exception:
            print("没有该选项,请重新选择:")
        if select == 1:
            ele = int(input("请输入元素:"))
            stack.push(ele)
        elif select == 2:
            print("栈顶元素为:", stack.pop())
        elif select == 3:
            stack.for_stack()
        elif select == 4:
            break
        else:
            print("没有该选项,请重新输入")


# 测试
test_array_stack(5)

用栈实现加减乘除综合计算器

思路分析

代码实现

# 用栈实现综合计算器
def calculator(expression: str):
    size = len(expression)
    num_stack = ArrayStack(size)  # 操作数栈
    oper_stack = ArrayStack(size)  # 操作符栈,存放运算符

    # 运算符运算结果
    opers = {
        "*": lambda x, y: x * y,
        "/": lambda x, y: x / y,
        "+": lambda x, y: x + y,
        "-": lambda x, y: x - y
    }
    # 运算符优先级
    oper_priority = {
        "*": 1,
        "/": 1,
        "+": 0,
        "-": 0
    }

    # 遍历表达式
    index = 0
    while True:
        if index >= len(expression):
            break
        i = expression[index]
        if "0" <= i <= "9":  # 是操作数
            # 判断下一个字符还是不是数字
            next = index + 1
            while True:  # 直到大于表达式长度或者下一个字符不是数字则退出循环
                if next >= len(expression):
                    break
                ch = expression[next]
                if "0" <= ch <= "9":
                    i += ch
                    index = next
                    next += 1
                else:
                    break

            num_stack.push(i)
        else:  # 是运算符
            # 如果操作符栈为空,则操作符 i 直接入栈
            if oper_stack.is_empty():
                oper_stack.push(i)
                index += 1
                continue

            # 获取 oper_stack 栈顶的运算符
            top = oper_stack.get_top()
            priority = oper_priority[i] - oper_priority[top] if top else 0
            # 如果当前操作符 i 大于栈顶的操作符,也直接入栈
            if priority > 0:
                oper_stack.push(i)

            # 否则,取出两个操作数和栈顶的操作符进行运算,奖结果入操作数栈,并且将操作符 i 入栈
            else:
                # 注意,由于栈先进后出,操作数栈顶的数是表达式中操作符右边的数
                # 所以 num1 和 num2 两个变量的位置不要弄错
                num2 = float(num_stack.pop())
                num1 = float(num_stack.pop())
                oper = oper_stack.pop()

                result = opers[oper](num1, num2)
                num_stack.push(result)
                oper_stack.push(i)
        index += 1

    # 遍历表达式完毕后,将两个栈中的操作数和操作符取出进行运算
    while not num_stack.is_empty() and not oper_stack.is_empty():
        num2 = float(num_stack.pop())
        num1 = float(num_stack.pop())
        oper = oper_stack.pop()
        num_stack.push(opers[oper](num1, num2))

    # 最后操作数栈中的结果就是表达式的运算结果
    print("{}={}".format(expression, num_stack.pop()))


calculator("50*8+25/6-2*7")
print(50*8+25/6-2*7)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
是一个非常适合实现计算器数据结构,因为它遵循后进先出(LIFO)的原则,与计算表达式的顺序相符合。下面是一个基于实现计算器的示例代码: ```python class Stack: def __init__(self): self.items = [] def is_empty(self): return len(self.items) == 0 def push(self, item): self.items.append(item) def pop(self): if not self.is_empty(): return self.items.pop() else: return None def peek(self): if not self.is_empty(): return self.items[-1] else: return None def size(self): return len(self.items) def calculate(expression): # 将操作符和操作数分别存储在两个中 operator_stack = Stack() operand_stack = Stack() # 定义一个操作符优先级字典 priority = {'+': 1, '-': 1, '*': 2, '/': 2} # 将表达式按空格分割为一个列表 tokens = expression.split() # 遍历表达式中的每个token for token in tokens: if token.isdigit(): # 如果是数字则压入操作数 operand_stack.push(int(token)) elif token in priority: # 如果是操作符则与操作符中的操作符比较优先级 while (not operator_stack.is_empty()) and \ (priority[operator_stack.peek()] >= priority[token]): # 如果操作符顶的优先级比当前操作符高,则进行计算 operand2 = operand_stack.pop() operand1 = operand_stack.pop() operator = operator_stack.pop() result = eval(str(operand1) + operator + str(operand2)) operand_stack.push(result) # 将当前操作符压入操作符 operator_stack.push(token) # 处理剩余的操作符 while not operator_stack.is_empty(): operand2 = operand_stack.pop() operand1 = operand_stack.pop() operator = operator_stack.pop() result = eval(str(operand1) + operator + str(operand2)) operand_stack.push(result) # 返回最终结果 return operand_stack.pop() ``` 这个实现中,我们使用了两个来存储操作符和操作数。具体实现过程如下: 1. 遍历表达式中的每个token。 2. 如果是数字,则将其压入操作数中。 3. 如果是操作符,则与操作符中的操作符比较优先级。如果操作符顶的优先级比当前操作符高,则进行计算,并将结果压入操作数中;否则,将当前操作符压入操作符中。 4. 处理完表达式中的所有token后,将操作符中剩余的操作符依次弹出并进行计算,直到操作符为空。 5. 返回最终结果。 注意,这个实现中使用了Python内置的`eval()`函数来进行计算。在实际应用中,应该使用更为安全的方法,例如手写计算函数或使用第三方库等。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值