中缀表达式求值

devtools/2024/9/25 21:41:58/

本文用于记录个人算法竞赛学习,仅供参考

 对于这个过程可以抽象为一颗二叉树来理解后序的做法(理解过程,但不是最终解法)

对于  1 + 2 * 2 - 1,可以通过中序遍历构建出一颗二叉树

 计算过程为

 

对于上述过程可以总结出一个计算规律:

1.叶子节点是数字,根节点是运算符

2.这颗二叉树自根节点到叶子节点的运算符的优先级是递增的,根节点的优先级最低

但这通过已经构建好的二叉树再来进行计算的,要计算其他表达式时,再人为构建一颗树是非常麻烦的,所以可以通过表达式从左向右扫描,通过优先级来构建一颗数,这个过程是通过栈来实现的。

1.扫描过程中,当前运算符优先级小于等于前一个运算符(栈顶的运算符)优先级时,代表当前运算符的的子树已经遍历完了,子树内的数字和符号合并计算成一个数值并加入栈内

2.当前运算符的优先级大于前一个运算符(栈顶的运算符)优先级时,代表子树还没有遍历完,直接将当前运算符入栈,等待后序操作

3.遇到’(‘时直接入栈,等待有序遇到’)‘再进行操作

4.遇到’)‘时求出()内的值,并入栈

代码如下

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <unordered_map>
#include <stack>
using namespace std;const int N = 100010;
//存数字的栈和存符号的栈
stack<int> nums;
stack<char> op;
//优先级
unordered_map<char,int> pr = {{'+',1},{'-',1},{'*',2},{'/',2}};//将两个数进行操作合并
void eval()
{auto b = nums.top();    nums.pop();auto a = nums.top();    nums.pop();auto c = op.top();      op.pop();if(c == '+'){nums.push(a + b);}else if(c == '-'){nums.push(a - b);}else if(c == '*'){nums.push(a * b);}else if(c == '/'){nums.push(a / b);}
}int main()
{string s;cin >> s;//从左向右扫描for(int i = 0; i < s.size(); i++){auto ch = s[i];//当前字符是数字if(isdigit(ch)){//读取数字串称为一个数字int x = 0;int j = i;while(j < s.size() && isdigit(s[j])){x = x * 10 + s[j++] - '0';}i = j - 1;nums.push(x);}//当前字符是'('else if(s[i] == '(')op.push('(');//求括号内的值else if(s[i] == ')'){while(op.top() != '('){eval();}//弹出'('op.pop();}//" + - * / "else{//当前运算符优先级小于前一个运算符(栈顶)的优先级while(!op.empty() && pr[s[i]] <= pr[op.top()]){eval();}//当前运算符入栈(如果当前运算符优先级大于前一个运算符优先级就直接入栈)op.push(s[i]);}}//将剩下的数字和运算符从右向左依次处理//数字最后剩下一个,运算符最后一个不剩while(op.size()){eval();}cout << nums.top() << endl;return 0;
}


http://www.ppmy.cn/devtools/4303.html

相关文章

微信小程序浮标,可以拖动,自动靠边隐藏一半客服图标功能

不多说&#xff0c;直接上代码。全屏拖动无抖动&#xff0c;中间停留自动靠边&#xff0c;拖动隐藏一半&#xff0c;可自己根据代码改动为自己想要的效果 js代码 import { tpStaticUrl,basictpStaticUrl } from "../../../envConfig"; let app getApp(); Componen…

nginx-http-flv配置

hls配置 hls配置放在 http.server里面 http {server {# HTTP监听端口listen 8002;location /hls {types {application/vnd.apple.mpegurl m3u8;video/mp2t ts;}alias ./temp/hls; # HLS文件存放路径&#xff0c;请替换为你实际的路径expires -1;add_header Cache-Control no…

软考系统架构设计师考试论文应试技巧

写论文是你展示系统分析水平的最佳时机&#xff0c;如果您面对三个论文问题的阐述&#xff0c;怎么才能让人相信你有项目实践经验&#xff0c;有较强的分析问题、解决问题的能力&#xff0c;怎么才能让你的论文就很有说服力呢&#xff1f;下面是湖北软考网小编总结出来的几条系…

Qt 6子窗口全屏显示

一、全屏显示效果 二、全屏相关函数 1,全屏显示函数 QWidget::showFullScreen(); // 此方法只对顶级窗口有效&#xff0c;对子窗口无效 2&#xff0c;恢复显示函数 QWidget::showNormal(); // 此方法也只对顶级窗口有效&#xff0c;对子窗口无效 3&#xff0c;最小化显示函…

中科亿海微-CL1656功能验证开发板

I. 引言 A. 研究背景与意义 CL1656是一款精度高、功耗低、成本低的5V单片低功耗运放&#xff0c;由核心互联公司研发制造&#xff0c;CL1656 是一个 16-bit、快速、低功耗逐次逼近型 ADC&#xff0c;吞吐速率高达 250 kSPS&#xff0c;并且内置低噪声、宽 带宽采样保持放大器。…

【Go语言基础面试题】

1.基础语法篇 1.1 和:的区别 是赋值:是声明赋值 1.2. 指针的作用&#xff1f; 指针用来保存变量的地址 解引用运算符*用于访问地址中的值地址运算符&用于返回变量的地址 1.3. Go允许多个返回值吗&#xff1f; 允许&#xff0c;返回两个string。func swap(x, y strin…

边缘计算网关有哪些用途及使用方法?-天拓四方

在数字化日益深入的今天&#xff0c;边缘计算网关作为一种重要的设备&#xff0c;正在越来越多地被应用于各种场景中。它不仅能够提升数据处理的速度和效率&#xff0c;还能在降低网络延迟的同时确保数据的安全性。本文将详细介绍边缘计算网关的用途及其使用方法&#xff0c;帮…

软考128-上午题-【软件工程】-白盒测试

一、白盒测试&#xff08;结构测试&#xff09; 白盒测试也称为结构测试&#xff0c;根据程序的内部结构和逻辑来设计测试用例&#xff0c;对程序的路径和过程进行测试&#xff0c;检查是否满足设计的需要。 白盒测试常用的技术是&#xff1a;逻辑覆盖、循环覆盖和基本路径测…