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

news2024/10/6 1:36:32

栈的基本介绍

出栈(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)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/952483.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python项目实战之《飞机大战游戏》

目录 一、Pygame库包简介 二、Pygame安装 三、项目开发思路 3.1前言 3.2飞机大战开发步骤 一、Pygame库包简介 Pygame是一个基于python的游戏开发库&#xff0c;它提供一系列的工具和接口&#xff0c;使开发人员能够轻松的创建各种类型的游戏&#xff0c;包括2D游戏和简单…

ptmalloc源码分析 - _int_malloc函数实现fastbins(06)

目录 一、_int_malloc内存分配的核心函数 二、bins的管理和chunk的结构 三、_int_malloc函数分配前的两个检查 四、REMOVE_FB原子实现fastbins的链表操作 五、fastbins的具体分配实现 一、_int_malloc内存分配的核心函数 前几章节&#xff0c;我们主要讲解了状态机malloc_…

xml

1.xml 1.1概述【理解】 万维网联盟(W3C) 万维网联盟(W3C)创建于1994年&#xff0c;又称W3C理事会。1994年10月在麻省理工学院计算机科学实验室成立。 建立者&#xff1a; Tim Berners-Lee (蒂姆伯纳斯李)。 是Web技术领域最具权威和影响力的国际中立性技术标准机构。 到目前为…

nginx反向代理 负载均衡

一、反向代理&#xff1a; 1.反向代理介绍&#xff1a; 反向代理&#xff1a;reverse proxy&#xff0c;指的是代理外网用户的请求到内部的指定的服务器&#xff0c;并将数据返回给用户的一种方式&#xff0c;这是用的比较多的一种方式。 Nginx 除了可以在企业提供高性能的web…

从2023蓝帽杯0解题heapSpary入门堆喷

从2023蓝帽杯0解题heapSpary入门堆喷 关于堆喷 堆喷射&#xff08;Heap Spraying&#xff09;是一种计算机安全攻击技术&#xff0c;它旨在在进程的堆中创建多个包含恶意负载的内存块。这种技术允许攻击者避免需要知道负载确切的内存地址&#xff0c;因为通过广泛地“喷射”堆…

三路排序算法(Java 实例代码)

目录 三路排序算法 一、概念及其介绍 二、适用说明 四、Java 实例代码 QuickSort3Ways.java 文件代码&#xff1a; 三路排序算法 一、概念及其介绍 三路快速排序是双路快速排序的进一步改进版本&#xff0c;三路排序算法把排序的数据分为三部分&#xff0c;分别为小于 v&…

blender 火焰粒子

效果展示 创建火焰模型 新建立方体&#xff08;shift A &#xff09;,添加表面细分修改器&#xff08;ctrl 2 &#xff09;&#xff0c;视图层级调整为 3 &#xff0c;这样布线更密集&#xff1b; 右键将模型转换为网格&#xff0c;tab 进入编辑模式&#xff0c;7 切换到顶…

基于 Debian 12 的 Devuan GNU+Linux 5 为软件自由爱好者而生

导读Devuan 开发人员宣布发布 Devuan GNULinux 5.0 “代达罗斯 “发行版&#xff0c;它是 Debian GNU/Linux 操作系统的 100% 衍生版本&#xff0c;不包含 systemd 和相关组件。 Devuan GNULinux 5 基于最新的 Debian GNU/Linux 12 “书虫 “操作系统系列&#xff0c;采用长期支…

Kafka3.0.0版本——手动调整分区副本示例

目录 一、服务器信息二、启动zookeeper和kafka集群2.1、先启动zookeeper集群2.2、再启动kafka集群 三、手动调整分区副本3.1、手动调整分区副本的前提条件3.2、手动调整分区副本的示例需求3.3、手动调整分区副本的示例 一、服务器信息 四台服务器 原始服务器名称原始服务器ip节…

新型安卓恶意软件使用Protobuf协议窃取用户数据

近日有研究人员发现&#xff0c;MMRat新型安卓银行恶意软件利用protobuf 数据序列化这种罕见的通信方法入侵设备窃取数据。 趋势科技最早是在2023年6月底首次发现了MMRat&#xff0c;它主要针对东南亚用户&#xff0c;在VirusTotal等反病毒扫描服务中一直未被发现。 虽然研究…

Linux--VMware的安装和Centos

一、VMware和Linux的关系 二、VMware的安装 VM_ware桌面虚拟机 最新中文版 软件下载 (weizhen66.cn) VMware-Workstation-Lite-16.2.2-19200509-精简安装注册版.7z - 蓝奏云 如果安装不成功&#xff0c;则设置BIOS 三、在VMware中加入Centos 下载地址&#xff1a; CentOS-…

深度学习论文分享(八)Learning Event-Driven Video Deblurring and Interpolation

深度学习论文分享&#xff08;八&#xff09;Learning Event-Driven Video Deblurring and Interpolation 前言Abstract1 Introduction2 Motivation2.1 Physical Model of Event-based Video Reconstruction2.2 Spatially Variant Triggering Threshold 3 Proposed Methods3.1 …

初学者如何制作属于自己的第一个网页?

如今&#xff0c;网页设计已经成为互联网世界不可或缺的一部分。随着网络的发展&#xff0c;越来越多的用户通过网页浏览信息、社交和购物。一个出色的网页设计能吸引用户的眼球&#xff0c;提升他们的浏览体验&#xff0c;从而提高用户满意度和忠诚度。那么&#xff0c;要设计…

机器学习——手写数字识别

0、&#xff1a;前言 这篇文章能够帮助你从数据到模型的整个过程实现不过至于安装第三方库等基础问题&#xff0c;本文不涉及&#xff0c;因为确实不难&#xff0c;搜一搜一大把本此实验运行环境为jupyter&#xff0c;当然通过pycharm也是可行的 1、数据&#xff1a; 手写数字…

简单了解网络基本概念

目录 一、网络含义 二、什么是以太网&#xff1f; 三、网络分类 四、网络架构 五、数据传输方式 六、双工模式 一、网络含义 在实际生活中我们用传输介质把独立的终端设备相互连接起来就构成了网络。 二、什么是以太网&#xff1f; 以太网是一种网络通信协议标准&#…

浅谈 Pytest+HttpRunner 如何展开接口测试!

软件测试有多种多样的方法和技术&#xff0c;可以从不同角度对它们进行分类。其中&#xff0c;根据软件生命周期&#xff0c;针对不同的测试对象与目标&#xff0c;可将测试过程分为 4 个阶段&#xff1a;单元测试、集成测试、系统测试和验收测试。本文着重介绍了如何借用 pyte…

【两周学会FPGA】从0到1学习紫光同创FPGA开发|盘古PGL22G开发板学习之数码管静态显示(四)

本原创教程由深圳市小眼睛科技有限公司创作&#xff0c;版权归本公司所有&#xff0c;如需转载&#xff0c;需授权并注明出处 适用于板卡型号&#xff1a; 紫光同创PGL22G开发平台&#xff08;盘古22K&#xff09; 一&#xff1a;盘古22K开发板&#xff08;紫光同创PGL22G开发…

postgresql-集合运算

postgresql-集合运算 简介UNIONINTERSECTEXCEPT分组与排序集合操作优先级 简介 数据库中的表&#xff08;table&#xff09;本质上就是由行&#xff08;row&#xff09;组成的集合。因此&#xff0c;PostgreSQL 同样支持集 合论中的集合操作&#xff0c;包括并集&#xff08;U…

CSS中的相对单位和绝对单位,以及rem自适应布局

在CSS中&#xff0c;我们经常需要指定元素的尺寸、间距和位置。为此&#xff0c;我们可以使用各种单位来定义这些值。本文将重点介绍CSS中的相对单位和绝对单位&#xff0c;并解释它们之间的区别。 相对单位 百分比&#xff08;%&#xff09;&#xff1a;百分比单位是相对于父元…

Go 官方标准编译器中所做的优化

本文是对#102 Go 官方标准编译器中实现的优化集锦汇总[1] 内容的记录与总结. 优化1-4: 字符串和字节切片之间的转化 1.紧跟range关键字的 从字符串到字节切片的转换&#xff1b; package mainimport ( "fmt" "strings" "testing")var cs10086 s…