中缀表达式求值

题目

  • 请写一个整数计算器,支持加减乘三种运算和括号。
    • 示例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,一经查实,立即删除!

相关文章

flask 路由(route)

web 框架使用路由技术来帮助用户记住应用程序的 url。无需从主页导航即可直接访问所需页面。 route() 装饰器用于将 url 绑定到函数&#xff1a; app.route(/hello) def hello_world(): return hello world url /hello 规则绑定到 hello_world() 函数。如果用户访问 url :…

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

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

1950F - 0, 1, 2, Tree!

题目链接&#xff1a;0, 1, 2, Tree! 本道题目其实就是一道贪心的题目&#xff0c;对于思维的考察较多。 思路&#xff1a; 1.首先我们想想什么情况下该树不存在&#xff1f; 由二叉树的性质可知每一个子节点个数为2的树都必须有两个&#xff0c;每一个子节点为1的树必须有…

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混合形状,人形装备,多种颜色可供选择。她将是一个完美的角色…

Python中直接根据网页内容导出为PDF或XLSX格式抓取网页内容,然后将其解析成适合导出到PDF或XLSX的结构

在Python中&#xff0c;直接根据网页内容导出为PDF或XLSX格式通常涉及几个步骤。首先&#xff0c;你需要抓取网页内容&#xff0c;然后将其解析成适合导出到PDF或XLSX的结构。下面是一些示例代码&#xff0c;展示如何完成这些任务。 网页内容抓取 你可以使用requests库来抓取…

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…

MVSNet复现及解析

目录 0.库安装1.参考链接2.调试过程 0.库安装 我在因为复现point-nerf才来研究MVSNet的&#xff0c;因此大部分库在复现point-nerf安装时候就已经安装了&#xff0c;剩下的基本上就只执行了下面两步&#xff1a; pip install tensorboardX-2.4.1-py2.py3-none-any.whl pip inst…

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…

Linux虚拟化————KVM

1、安装kvm虚拟化套件 [rootbogon ~]# yum -y install virt* 2、启动服务 [rootbogon ~]# systemctl start libvirtd [rootbogon ~]# systemctl status libvirtd ● libvirtd.service - Virtualization daemonLoaded: loaded (/usr/lib/systemd/system/libvirtd.service; di…

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

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

结构体二级指针

1. 其实*p和**pm都是差不多的&#xff0c;一个是告诉系统是一级指针和二级指针&#xff0c;判断他们是否是二级指针还是看他们保存的是否是指针变量的地址 2.写的程序哪段跳过就是哪段有问题 #include <stdio.h> #include <string.h> #include <stdlib.h>…

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

时间&#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外部中断模式&…

东岸科技将赴港IPO,冲刺催收第一股

来源 | 镭射财经&#xff08;leishecaijing&#xff09; 「镭射财经」独家获悉&#xff0c;东岸科技即将开启IPO&#xff0c;向港交所递交上市申请。计划上市的为公司科技板块&#xff0c;拟募集资金主要用于不良资产管理数字化创新。 今年3月&#xff0c;东岸科技董事长朱铁…

Linux LVM 逻辑卷管理

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