中缀表达式求值

题目

  • 请写一个整数计算器,支持加减乘三种运算和括号。
    • 示例1
      输入:“1+2”
      返回值:3
    • 示例2
      输入:“(2*(3-4))*5”
      返回值:-10
    • 示例3
      输入:“3+2*3*4-1”
      返回值:26

思路

  • 经典的中缀表达式求值。常用思路,将其转为后缀表达式(后缀表达式的特点:遇到运算符则将前两个数拿出来运算,便于计算机计算),边转边求值。
  • 读到左括号 ( 较为特殊,读到左括号时直接入栈,
  • 本题中运算符优先级:左括号或栈顶为空、乘、加减 、右括号。
  • 读到右括号时一直出栈直到一个左括号出栈。

算法步骤

  • 遍历字符串,当 遍历到的字符是数字 时,直接将其压入数字栈。
  • 否则,当 遍历到的字符是运算符 时,判断字符,直到字符串读完:
    • 若符号栈为空,则直接将其压入符号栈。
    • 若符号栈非空,则判断符号栈栈顶的运算符优先级:
      • 若 遍历到的运算符符号的优先级 > 符号栈栈顶元素的优先级,或符号栈空,则将读取的运算符压入符号栈。
      • 若 遍历到的运算符符号的优先级 ≤ 符号栈栈顶元素的优先级,则将其出栈,并从数字栈弹出两个元素进行该运算,先弹出的为右操作数,后弹出的为左操作数,将结果压入数字栈。
  • 最后,若符号栈非空,则弹出栈顶元素,并从数字栈弹出两个元素来进行该运算,重复该操作直到符号栈空。
  • 符号栈为空后,弹出数字栈栈顶元素作为结果。
  • 返回数值站栈顶元素作为最终结果。
int solve(string s) {stack<char> sign;stack<int> num;for (int i = 0; i < s.length(); i++) {//若当前遍历到的字符为数字,则将连续的数放入val栈if (s[i] >= '0' && s[i] <= '9') {int rear = i;while ((rear + 1) < s.length() && s[rear + 1] >= '0' && s[rear + 1] <= '9') {rear++;}int n = 0;for (int j = rear; j >= i; j--) {n += (s[j] - '0') * pow(10, (rear - j));}i = rear;num.push(n);}//【优先级较大】当前遍历到的字符为(、*  或  ops符号栈为空,则将该符号压入符号栈else if (s[i] == '(' || s[i] == '*'|| sign.size() == 0   ){sign.push(s[i]);}//【优先级较小】当前遍历到的字符为+、-else if (s[i] == '+' || s[i] == '-') {while (1) {if (sign.size() == 0)break;if (sign.top() == '*') {sign.pop();int n2 = num.top();num.pop();int n1 = num.top();num.pop();num.push(n1 * n2);}else if (sign.top() == '+') {sign.pop();int n2 = num.top();num.pop();int n1 = num.top();num.pop();num.push(n1 + n2);}else if (sign.top() == '-') {sign.pop();int n2 = num.top();num.pop();int n1 = num.top();num.pop();num.push(n1 - n2);}else {break;}}sign.push(s[i]);}// 读到右括号时符号栈就一直出栈直到一个左括号出栈。else if (s[i] == ')') {while (1) {if (sign.size() == 0) {break;}else if (sign.top() == '(') {sign.pop();break;}else if (sign.top() == '+') {sign.pop();int n2 = num.top();num.pop();int n1 = num.top();num.pop();num.push(n1 + n2);}else if (sign.top() == '-') {sign.pop();int n2 = num.top();num.pop();int n1 = num.top();num.pop();num.push(n1 - n2);}else if (sign.top() == '*') {sign.pop();int n2 = num.top();num.pop();int n1 = num.top();num.pop();num.push(n1 * n2);}}}}//最后,若符号栈非空,则弹出栈顶元素,并从数字栈弹出两个元素来进行该运算。重复该操作直到符号栈空。while (sign.size() != 0) {if (sign.top() == '+') {sign.pop();int n2 = num.top();num.pop();int n1 = num.top();num.pop();num.push(n1 + n2);}else if (sign.top() == '-') {sign.pop();int n2 = num.top();num.pop();int n1 = num.top();num.pop();num.push(n1 - n2);}else if (sign.top() == '*') {sign.pop();int n2 = num.top();num.pop();int n1 = num.top();num.pop();num.push(n1 * n2);}}//弹出数字栈栈顶元素,即得结果。return num.top();
}

实例

#include <iostream>
#include <stack>
using namespace std;int solve(string s) {// write code herestack<char> sign;stack<int> num;for (int i = 0; i < s.length(); i++) {//若当前遍历到的字符为数字,则将连续的数放入val栈if (s[i] >= '0' && s[i] <= '9') {int rear = i;while ((rear + 1) < s.length() && s[rear + 1] >= '0' && s[rear + 1] <= '9') {rear++;}int n = 0;for (int j = rear; j >= i; j--) {n += (s[j] - '0') * pow(10, (rear - j));}i = rear;num.push(n);}//若 当前遍历到的字符为(、*  或  ops符号栈为空,则将该符号压入符号栈else if (s[i] == '(' || s[i] == '*'|| sign.size() == 0   ){sign.push(s[i]);}//若 当前遍历到的字符为+、-else if (s[i] == '+' || s[i] == '-') {while (1) {if (sign.size() == 0)break;if (sign.top() == '*') {sign.pop();int n2 = num.top();num.pop();int n1 = num.top();num.pop();num.push(n1 * n2);}else if (sign.top() == '+') {sign.pop();int n2 = num.top();num.pop();int n1 = num.top();num.pop();num.push(n1 + n2);}else if (sign.top() == '-') {sign.pop();int n2 = num.top();num.pop();int n1 = num.top();num.pop();num.push(n1 - n2);}else {break;}}sign.push(s[i]);}else if (s[i] == ')') {while (1) {if (sign.size() == 0) {break;}else if (sign.top() == '(') {sign.pop();break;}else if (sign.top() == '+') {sign.pop();int n2 = num.top();num.pop();int n1 = num.top();num.pop();num.push(n1 + n2);}else if (sign.top() == '-') {sign.pop();int n2 = num.top();num.pop();int n1 = num.top();num.pop();num.push(n1 - n2);}else if (sign.top() == '*') {sign.pop();int n2 = num.top();num.pop();int n1 = num.top();num.pop();num.push(n1 * n2);}}}}//最后,若符号栈非空,则弹出栈顶元素,并从数字栈弹出两个元素来进行该运算。重复该操作直到符号栈空。while (sign.size() != 0) {if (sign.top() == '+') {sign.pop();int n2 = num.top();num.pop();int n1 = num.top();num.pop();num.push(n1 + n2);}else if (sign.top() == '-') {sign.pop();int n2 = num.top();num.pop();int n1 = num.top();num.pop();num.push(n1 - n2);}else if (sign.top() == '*') {sign.pop();int n2 = num.top();num.pop();int n1 = num.top();num.pop();num.push(n1 * n2);}}//弹出数字栈栈顶元素,即得结果。return num.top();
}int main()
{string mys = "1+3*(5+2)";cout<< mys<<"=" << solve(mys) << endl;return 0;
}

在这里插入图片描述

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

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

相关文章

“面包板”是什么?有啥用?

同学们大家好&#xff0c;今天我们继续学习杨欣的《电子设计从零开始》&#xff0c;这本书从基本原理出发&#xff0c;知识点遍及无线电通讯、仪器设计、三极管电路、集成电路、传感器、数字电路基础、单片机及应用实例&#xff0c;可以说是全面系统地介绍了电子设计所需的知识…

Vue3从入门到实战:深度掌握组件通信(上部曲)

props的概念&#xff1a; 当你使用Vue 3的组合式API时&#xff0c;props就是一种让你可以从父组件向子组件传递数据的方式。你可以想象成你在给子组件写一封信&#xff0c;把需要传递的信息放在信封里。 在Vue 3中&#xff0c;你可以在子组件的代码中定义props&#xff0c;就…

Dryad Girl Fawnia

一个可爱的Dryad Girl Fawnia的三维模型。她有ARKit混合形状,人形装备,多种颜色可供选择。她将是一个完美的角色,幻想或装扮游戏。 🔥 Dryad Girl | Fawnia 一个可爱的Dryad Girl Fawnia的三维模型。她有ARKit混合形状,人形装备,多种颜色可供选择。她将是一个完美的角色…

Web 题记

[极客大挑战 2019]LoveSQL 看到这种就肯定先想到万能密码&#xff0c;试试&#xff0c;得到了用户名和密码 总结了一些万能密码&#xff1a; or 11 oror admin admin-- admin or 44-- admin or 11-- admin888 "or "a""a admin or 22# a having 11# a havin…

Unity引擎Shader 技术点解释

Shader 类 定义&#xff1a; Shader 类是 Unity 中用于封装着色器程序的实例。它允许开发者在同一个文件中定义多个着色器程序&#xff0c;并指导 Unity 如何使用它们。 兼容性&#xff1a; Shader 类需要与 Unity 的渲染管线兼容。Unity 提供了两种主要的渲染管线&#xf…

C++ 之 newmat 矩阵运算库使用笔记

文章目录 Part.I IntroductionChap.I newmat 简介 Part.II 安装与编译Chap.I 直接使用源码Chap.II 基于 CMake 使用源码Chap.III 编译成库 Part.III 关于矩阵的构造与运算Chap.I 矩阵的构造与初始化Chap.II 矩阵的运算Chap.III 矩阵维数和类型的更改Chap.IV 矩阵最值统计 Refer…

【避坑/个人总结】CARLA仿真遇到问题——AttributeError: module “numpy“ has no attribute “bool“

问题描述 执行以下命令时&#xff1a; ./CarlaUE4.sh -prefernvidia // 以及 ros2 launch carla_shenlan_bridge_ego_vis carla_bridge_ego_vehilce.launch.py 出现以下的问题&#xff1a; 其中的报错类型及具体为&#xff1a;AttributeError: module "numpy" has…

线下商家地图标注服务/店铺地图定位/商铺地图标注服务源码

简介&#xff1a; 前台 单店标注信息提交&#xff0c; 连锁店标注信息提交 &#xff0c;支付订单查询&#xff0c;用户问题反馈 后台 系统基本设置&#xff0c;反馈信息查看&#xff0c;订单信息管理&#xff0c;地图信息管理&#xff0c;管理员密码设置&#xff0c;集成微信…

香港科技大学广州|数据科学与分析学域硕博招生宣讲会—华东师范大学专场

时间&#xff1a;2024年4月25日&#xff08;星期四&#xff09;13:30 地点&#xff1a;华东师范大学普陀校区文附楼507 报名链接&#xff1a;https://www.wjx.top/vm/Q0cKTUI.aspx# 跨学科研究领域 *数据驱动的人工智能和机器学习 *统计学习和建模 工业和商业分析 *特定行业…

鲲鹏920RDMA应用示例代码

当前针对鲲鹏920服务器&#xff0c;编写了RDMA通信传输代码&#xff0c;首先采用TCP socket进行管理信息获取&#xff0c;然后调用verbs函数接口进行数据传输。需要安装rdma-core-devel库才可以编译 代码如下&#xff1a; /** rdma_lib.h** Created on: 2021年1月1日* A…

在Linux系统中设定延迟任务

一、在系统中设定延迟任务要求如下&#xff1a; 要求&#xff1a; 在系统中建立easylee用户&#xff0c;设定其密码为easylee 延迟任务由root用户建立 要求在5小时后备份系统中的用户信息文件到/backup中 确保延迟任务是使用非交互模式建立 确保系统中只有root用户和easylee用户…

【NUCLEO-G071RB】004——GPIO-按键EXTI外部中断控制LED闪烁

NUCLEO-G071RB&#xff1a;004——GPIO-按键EXTI外部中断控制LED闪烁 设计目标电路原理图芯片配置程序修改 设计目标 电路原理图 与NUCLEO-G071RB&#xff1a;003——GPIO-按键控制LED灯相同 芯片配置 1、PC13&#xff08;B1&#xff09;&#xff1a;EXTI外部中断模式&…

Linux LVM 逻辑卷管理

Logical Volume Manager&#xff0c;逻辑卷管理 能够在保持现有数据不变的情况下动态调整磁盘容量&#xff0c;从而提高磁盘管理的灵活性/boot分区用于存放引导文件&#xff0c;不能基于LVM创建 三大概念&#xff1a; 物理卷PV基于硬盘或分区设备创建而来&#xff0c;生成N多…

基于SpringBoot的“滴答拍摄影项目”的设计与实现(源码+数据库+文档+PPT)

基于SpringBoot的“滴答拍摄影项目”的设计与实现&#xff08;源码数据库文档PPT) 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBoot 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 滴答拍摄影项目结构图 管理员登录首页界面图 用…

【Linux】git

大家好&#xff0c;我是苏貝&#xff0c;本篇博客带大家了解Linux的编译器-gcc/g&#xff0c;如果你觉得我写的还不错的话&#xff0c;可以给我一个赞&#x1f44d;吗&#xff0c;感谢❤️ 目录 1.安装git2.在gitee上创建仓库3.首次配置4.下载仓库到本地5.三板斧6.git log7.gi…

待研究技术

Fabric.js H5 Canvas的js库 Fabric.js是一个用于创建交互式的HTML5 Canvas应用程序的JavaScript库。它提供了一个简单而强大的API&#xff0c;用于在Web浏览器中绘制和操作图形对象。Fabric.js可以用于创建各种图形应用程序&#xff0c;例如绘图编辑器、图像编辑器、流程图、地…

JavaSE-13笔记【集合2(+2024新)】

文章目录 3.Map3.1 Map继承结构3.2 Map接口的常用方法3.3 遍历Map3.4 HashMap集合3.4.1 HashMap集合key的特点3.4.2 HashMap集合的key存储自定义类型3.4.3 哈希表3.4.3.1 哈希表的介绍3.4.3.2 哈希表的存储原理 3.4.4 存放在HashMap和HashSet集合key部分的元素必须同时重写hash…

2024年在Vim中开发vue2+java

neovim 0.5刚出来的时代&#xff0c;那时刚有lua插件我很狂热。每天沉迷于打造自己的IDE之中。写过一堆相关的博客&#xff0c;也录过一些视频教程。后来发现neovim的接口和插件更新的很快&#xff0c;导致配置文件要不定期的修改&#xff0c;才能保证新版本的插件的适配。我也…

理解思维链Chain of Thought(CoT)

Chain of Thought&#xff08;CoT&#xff09;&#xff0c;即“思维链”&#xff0c;是人工智能领域中的一个概念&#xff0c;特别是在自然语言处理和推理任务中。它指的是一种推理过程&#xff0c;其中模型在生成最终答案之前&#xff0c;先逐步推导出一系列的中间步骤或子目标…

部署Zabbix5.0

一.部署zabbix客户端 端口号10050 zabbix 5.0 版本采用 golang 语言开发的新版本客户端 agent2 。 zabbix 服务端 zabbix_server 默认使用 10051 端口&#xff0c;客户端 zabbix_agent2 默认使用 10050 端口。 1.1.关闭防火墙和selinux安全模块 systemctl disable --now fir…