信息学奥赛 1356:表达式求值 (calc) 从原理到 AC,5 步构建表达式树

发布时间:2026/7/11 5:02:20

信息学奥赛 1356:表达式求值 (calc) 从原理到 AC,5 步构建表达式树
信息学奥赛 1356表达式求值 (calc) 从原理到 AC5 步构建表达式树在信息学竞赛中表达式求值是一个经典问题。本文将深入解析《信息学奥赛一本通》1356题计算(calc)的第三种解法——表达式树。不同于直接求值或转换为后缀表达式的方法表达式树通过树形结构直观展现运算优先级为处理复杂表达式提供了清晰的解决方案。1. 表达式树基础概念表达式树是一种特殊的二叉树结构用于表示数学表达式。它具有以下特点叶子节点存储操作数数值内部节点存储运算符如、-、*、/子树关系每个运算符的左右子树代表其运算对象struct Node { char op; // 运算符内部节点 int val; // 数值叶子节点 int left, right;// 左右子节点索引 };表达式树的求值过程遵循后序遍历原则先计算左子树的值再计算右子树的值最后用当前节点的运算符对两个结果进行运算。这种结构与运算优先级天然契合特别适合处理带括号的复杂表达式。2. 双栈构建表达式树构建表达式树的核心算法使用双栈法一个操作数栈存储节点索引一个运算符栈处理运算优先级。以下是详细步骤2.1 初始化与预处理stackint numStack; // 操作数栈存储节点索引 stackchar opStack; // 运算符栈 string s; // 输入表达式 s ); // 添加哨兵运算符确保最终清空栈2.2 运算符优先级定义int priority(char op) { switch(op) { case (: return 0; // 最低优先级保证括号内运算符入栈 case : case -: return 1; case *: case /: return 2; default: return -1; // 非法运算符 } }2.3 核心算法流程遇到数字创建叶子节点并入操作数栈if(isdigit(s[i])) { int val 0; while(isdigit(s[i])) val val*10 (s[i]-0); nodes[idx] {\0, val, -1, -1}; numStack.push(idx); }遇到运算符比较优先级并处理栈顶高优先级运算符while(!opStack.empty() priority(opStack.top()) priority(s[i])) { char op opStack.top(); opStack.pop(); int right numStack.top(); numStack.pop(); int left numStack.top(); numStack.pop(); nodes[idx] {op, 0, left, right}; numStack.push(idx); } opStack.push(s[i]);遇到括号左括号直接入栈右括号处理到左括号为止if(s[i] () opStack.push((); else if(s[i] )) { while(opStack.top() ! () { // 同运算符处理逻辑 } opStack.pop(); // 弹出左括号 }3. 完整C实现与注释#include bits/stdc.h using namespace std; const int MAXN 1005; struct Node { char op; int val, left, right; } nodes[MAXN]; int idx 0; int priority(char op) { switch(op) { case (: return 0; case : case -: return 1; case *: case /: return 2; default: return -1; } } int calc(int a, int b, char op) { switch(op) { case : return a b; case -: return a - b; case *: return a * b; case /: return a / b; default: return 0; } } int main() { stackint numStack; stackchar opStack; string s; cin s; s ); // 哨兵 for(int i 0; i s.size(); ) { if(isdigit(s[i])) { int val 0; while(i s.size() isdigit(s[i])) val val*10 (s[i]-0); nodes[idx] {\0, val, -1, -1}; numStack.push(idx); } else { if(s[i] () { opStack.push((); i; } else if(s[i] )) { while(opStack.top() ! () { char op opStack.top(); opStack.pop(); int r numStack.top(); numStack.pop(); int l numStack.top(); numStack.pop(); nodes[idx] {op, 0, l, r}; numStack.push(idx); } opStack.pop(); i; } else { // 运算符 while(!opStack.empty() priority(opStack.top()) priority(s[i])) { char op opStack.top(); opStack.pop(); int r numStack.top(); numStack.pop(); int l numStack.top(); numStack.pop(); nodes[idx] {op, 0, l, r}; numStack.push(idx); } opStack.push(s[i]); i; } } } cout nodes[numStack.top()].val; return 0; }4. 表达式树的优势与应用相比其他解法表达式树具有独特优势方法时间复杂度空间复杂度可扩展性可视化程度直接求值O(n)O(n)中等低后缀表达式O(n)O(n)高中表达式树O(n)O(n)最高高典型应用场景需要多次求值的表达式构建一次多次计算表达式化简与优化数学公式的可视化展示编译器前端处理5. 常见问题与调试技巧5.1 易错点分析括号匹配忘记处理右括号后的栈操作运算符优先级比较时漏掉等号导致错误数字解析多位数字处理不完整边界条件空表达式或单数字表达式5.2 调试建议打印中间状态输出运算符栈和操作数栈的变化可视化表达式树通过DFS打印树结构void printTree(int root, int depth 0) { if(root -1) return; printTree(nodes[root].right, depth1); cout string(depth*4, ); if(nodes[root].op) cout nodes[root].op endl; else cout nodes[root].val endl; printTree(nodes[root].left, depth1); }表达式树不仅是竞赛中的高效工具更是理解编译器工作原理的重要桥梁。掌握这一数据结构对提升算法思维和工程能力都大有裨益。

相关新闻

VC++电子地图开发实战:从MFC框架到自主渲染引擎的架构设计与性能优化

VC++电子地图开发实战:从MFC框架到自主渲染引擎的架构设计与性能优化

2026/7/11 5:02:20

1. 项目概述:为什么选择VC做电子地图开发?最近在整理硬盘,翻出来一个十多年前的老项目,叫“GeoExpert”。这名字现在听起来有点土,但当时可是我们团队花了小半年时间,用Visual C(VC)…

AI工程实践:从模型部署到智能体开发的理性落地指南

AI工程实践:从模型部署到智能体开发的理性落地指南

2026/7/11 5:02:20

1. 先理解皮萨里德斯的核心观点:AI不是万能的生产率增长解药诺贝尔经济学奖得主皮萨里德斯提出的观点很值得技术从业者认真思考:AI无法让西方经济体重返生产率快速增长时代。这个判断不是否定AI的价值,而是提醒我们要理性看待AI在生产率提升中…

Cadence Orcad原理图DRC规则检查

Cadence Orcad原理图DRC规则检查

2026/7/11 5:02:20

1,首先,鼠标点击原理图,然后再点击右上方的小勾图标 design rules check2,option选项的界面3,电气规则设置4,物理规则设置5,,报告选项6,ERC矩阵相交的点表示连接关系是否…

C# WinForm CAN上位机开发:基于周立功DLL实现3步收发与实时曲线绘制

C# WinForm CAN上位机开发:基于周立功DLL实现3步收发与实时曲线绘制

2026/7/11 6:52:26

C# WinForm CAN上位机开发实战:基于周立功DLL的3步高效通信与动态可视化1. 环境搭建与硬件准备工控领域的CAN通信开发往往始于硬件选型与环境配置。以周立功USBCAN-II为例,这款经典设备支持最高1Mbps的通信速率,其配套的ControlCAN.dll动态库…

AI 是怎么操作浏览器的——browser use 实现原理

AI 是怎么操作浏览器的——browser use 实现原理

2026/7/11 6:52:26

AI Agent 操作浏览器的方式分两种。第一种是截图发给 LLM,LLM 返回一个 (x, y) 坐标,让浏览器自动化工具在该坐标模拟点击;第二种是把网页转换成一棵带编号的文本树,LLM 从文本树里选编号,浏览器自动化工具按编号定位到…

OpenAI DevDay 2026:AI开发者大会报名指南与技术亮点解析

OpenAI DevDay 2026:AI开发者大会报名指南与技术亮点解析

2026/7/11 6:52:26

OpenAI DevDay 2026 开发者大会报名即将截止,这是 OpenAI 面向全球开发者举办的年度技术盛会。对于正在构建 AI 应用、研究前沿模型或希望深入了解 OpenAI 技术栈的工程师和创业者来说,这是直接与 OpenAI 团队交流、获取第一手技术资料的关键机会。本次大…

双节锂电池主动均衡方案:MP2672A与TM4C129LNCZAD应用

双节锂电池主动均衡方案:MP2672A与TM4C129LNCZAD应用

2026/7/11 6:52:26

1. 项目背景与核心需求在便携式电子设备和储能系统中,双节锂离子电池串联方案因其更高的输出电压和能量密度而广泛应用。但串联电池组存在一个固有难题:由于制造工艺差异和使用环境不同,各单体电池的电压会出现不均衡。这种不均衡轻则降低电池…

WIN11 安装CODEX

WIN11 安装CODEX

2026/7/11 6:52:26

使用powershell 管理员模式winget install Codex -s msstore如果安装异常用以下命令修复,同样在pwoershell 管理员模式$progressPreference silentlyContinue Write-Host "Installing WinGet PowerShell module from PSGallery..." Install-PackageProvi…

AI教育技术架构解析:从个性化学习到工程实践

AI教育技术架构解析:从个性化学习到工程实践

2026/7/11 6:42:25

最近在技术圈看到一个很有意思的现象:美国一些高净值家庭开始将孩子送入所谓的"AI私校",每年支付数万美元学费,实际上却成为了未经验证的AI教育技术的测试者。这种现象背后反映的是AI技术在教育领域的快速渗透,以及家长…

解锁AMD Ryzen处理器深层性能:SMU Debug Tool完全指南

解锁AMD Ryzen处理器深层性能:SMU Debug Tool完全指南

2026/7/10 22:32:48

解锁AMD Ryzen处理器深层性能:SMU Debug Tool完全指南 【免费下载链接】SMUDebugTool A dedicated tool to help write/read various parameters of Ryzen-based systems, such as manual overclock, SMU, PCI, CPUID, MSR and Power Table. 项目地址: https://gi…

6个月转型AI工程师:实战路径与核心技能

6个月转型AI工程师:实战路径与核心技能

2026/7/9 18:28:30

1. 项目概述:6个月转型AI工程师的可行性路径在2023年大模型技术爆发的背景下,AI工程师岗位需求同比增长217%(LinkedIn数据)。不同于传统算法工程师需要3-5年培养周期,现代AI工程师更侧重工程化落地能力。我在硅谷科技公…

YOLOv5模型剪枝与量化实战:边缘设备部署优化

YOLOv5模型剪枝与量化实战:边缘设备部署优化

2026/7/10 6:57:56

1. 项目背景与核心价值在计算机视觉领域,YOLOv5因其出色的实时检测性能成为工业界宠儿。但当我们尝试将其部署到边缘设备(如树莓派、Jetson Nano或手机终端)时,立刻会遇到两个致命问题:模型体积庞大(原始YO…

WechatDecrypt技术解析:深入理解微信数据库AES-256-CBC解密机制

WechatDecrypt技术解析:深入理解微信数据库AES-256-CBC解密机制

2026/7/11 0:02:03

WechatDecrypt技术解析:深入理解微信数据库AES-256-CBC解密机制 【免费下载链接】WechatDecrypt 微信消息解密工具 项目地址: https://gitcode.com/gh_mirrors/we/WechatDecrypt 在数字隐私日益重要的今天,微信聊天记录作为个人数字资产的重要组成…

5分钟搞定Kodi字幕难题:智能字幕插件让你追剧无忧 [特殊字符]

5分钟搞定Kodi字幕难题:智能字幕插件让你追剧无忧 [特殊字符]

2026/7/11 0:02:03

5分钟搞定Kodi字幕难题:智能字幕插件让你追剧无忧 🎬 【免费下载链接】zimuku_for_kodi Kodi 插件,用于从「字幕库」网站下载字幕 项目地址: https://gitcode.com/gh_mirrors/zi/zimuku_for_kodi 还记得那个深夜吗?你刚下载…

PostgreSQL 备份与恢复实战:从 pg_dump 到时间点恢复的生产级方案

PostgreSQL 备份与恢复实战:从 pg_dump 到时间点恢复的生产级方案

2026/7/11 0:02:03

PostgreSQL 备份与恢复实战:从 pg_dump 到时间点恢复的生产级方案 一、数据库备份最容易被忽略的问题,不是「有没有做备份」,而是「备份能不能恢复、恢复要多久、以及恢复后的数据对不对」 很多团队做数据库备份的方式是「写个 cron job&am…