news 2026/4/16 10:41:42

C++拓展:计算器实现——从中缀表达式到逆波兰表达式

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C++拓展:计算器实现——从中缀表达式到逆波兰表达式

一、核心原理

在开始代码实现之前,我们需要先明确两个核心步骤:逆波兰表达式的求值过程,以及中缀表达式转后缀表达式的转换规则。这两个步骤是计算器实现的基石,理解其原理是后续代码编写的关键。

1.1 逆波兰表达式(后缀表达式)求值原理

逆波兰表达式的求值过程依赖栈这种数据结构,利用栈“后进先出”的特性,能够快速完成运算。其核心逻辑如下:

  1. 建立一个栈,用于存储运算数;
  2. 依次遍历逆波兰表达式中的每个元素;
  3. 如果当前元素是运算数,直接将其入栈;
  4. 如果当前元素是运算符,弹出栈顶的两个运算数(注意:先弹出的是右运算数,后弹出的是左运算数);
  5. 使用当前运算符对两个运算数进行计算,将结果作为新的运算数入栈;
  6. 遍历完表达式后,栈中剩余的唯一元素就是最终的运算结果。

举个简单的例子:逆波兰表达式1 2 + 3 4 * -(对应的中缀表达式为1+2-(3*4))的求值过程:

  • 遍历到1,入栈,栈:[1];
  • 遍历到2,入栈,栈:[1,2];
  • 遍历到+,弹出 2(右)和 1(左),计算 1+2=3,入栈,栈:[3];
  • 遍历到3,入栈,栈:[3,3];
  • 遍历到4,入栈,栈:[3,3,4];
  • 遍历到*,弹出 4(右)和 3(左),计算 3*4=12,入栈,栈:[3,12];
  • 遍历到-,弹出 12(右)和 3(左),计算 3-12=-9,入栈,栈:[-9];
  • 遍历结束,结果为 - 9。

这个过程是无需考虑运算符优先级的,因为逆波兰表达式已经在转换过程中处理了优先级和括号,求值逻辑非常直观。

1.2 中缀表达式转后缀表达式原理

中缀表达式转后缀表达式是计算器实现的核心难点,其关键在于利用栈处理运算符的优先级和括号。转换规则如下:

1.2.1 转换规则
  1. 建立一个栈,用于存储运算符;
  2. 依次遍历中缀表达式中的每个字符;
  3. 如果当前字符是运算数(0-9),直接输出到后缀表达式中;
  4. 如果当前字符是左括号(,直接入栈;
  5. 如果当前字符是右括号),则弹出栈顶运算符并输出,直到遇到左括号(为止(左括号弹出但不输出);
  6. 如果当前字符是运算符(+、-、*、/):
    • 若栈为空,或栈顶元素是左括号(,则当前运算符直接入栈;
    • 若当前运算符的优先级高于栈顶运算符,直接入栈;
    • 若当前运算符的优先级低于或等于栈顶运算符,则弹出栈顶运算符并输出,重复此过程,直到栈为空或栈顶运算符优先级低于当前运算符,最后将当前运算符入栈;
  7. 遍历完中缀表达式后,弹出栈中剩余的所有运算符,依次输出到后缀表达式中。

1.2.2 运算符优先级定义

为了判断运算符优先级,我们需要明确:*/的优先级高于+-。本文定义优先级如下:

  • +-:优先级 1;
  • */:优先级 2。
1.2.3 转换案例

这里以中缀表达式1+2-(3*4+5)-7为例,为大家详细展示转换过程:

遍历字符

栈状态(运算符)

后缀表达式

说明

1

1

运算数,直接输出

[+]

1

栈空,入栈

2

[+]

1 2

运算数,直接输出

-

[-]

1 2 +

-优先级等于栈顶+,弹出+输出,栈空后入栈-

(

[-, (]

1 2 +

左括号,直接入栈

3

[-, (]

1 2 + 3

运算数,直接输出

*

[-, (, *]

1 2 + 3

栈顶是(,入栈*

4

[-, (, *]

1 2 + 3 4

运算数,直接输出

[-, (, +]

1 2 + 3 4 *

+优先级低于栈顶*,弹出*输出,栈顶是(,入栈+

5

[-, (, +]

1 2 + 3 4 * 5

运算数,直接输出

)

[-]

1 2 + 3 4 * 5 +

右括号,弹出运算符直到(,(弹出不输出

-

[-]

1 2 + 3 4 * 5 + -

-优先级等于栈顶-,弹出-输出,栈空后入栈-

7

[-]

1 2 + 3 4 * 5 + - 7

运算数,直接输出

遍历结束

1 2 + 3 4 * 5 + - 7 -

弹出栈中剩余-,输出

最终得到的后缀表达式为1 2 + 3 4 * 5 + - 7 -,对应的计算结果为1+2-(3*4+5)-7 = 3 - 17 -7 = -21,后续求值过程将验证这一结果。

二、逆波兰表达式求值实现(evalRPN)

2.1 功能说明

实现一个函数evalRPN,输入为逆波兰表达式的字符串数组(每个元素为运算数或运算符),输出为计算结果。

2.2 代码实现

代码语言:javascript

AI代码解释

#include <iostream> #include <vector> #include <stack> #include <string> #include <cassert> using namespace std; class Calculator { public: // 逆波兰表达式求值 int evalRPN(const vector<string>& tokens) { stack<int> numStack; // 存储运算数的栈 for (size_t i = 0; i < tokens.size(); ++i) { const string& token = tokens[i]; // 判断当前token是运算数还是运算符 if (isOperator(token)) { // 运算符:弹出两个运算数计算 assert(numStack.size() >= 2 && "逆波兰表达式格式错误,运算符数量过多"); int rightNum = numStack.top(); numStack.pop(); int leftNum = numStack.top(); numStack.pop(); // 根据运算符计算结果并入栈 int result = calculate(leftNum, rightNum, token[0]); numStack.push(result); } else { // 运算数:转换为int后入栈 numStack.push(stoi(token)); } } assert(numStack.size() == 1 && "逆波兰表达式格式错误,运算数数量过多"); return numStack.top(); } private: // 判断字符串是否为运算符(+、-、*、/) bool isOperator(const string& s) { return s == "+" || s == "-" || s == "*" || s == "/"; } // 执行二元运算 int calculate(int left, int right, char op) { switch (op) { case '+': return left + right; case '-': return left - right; case '*': return left * right; case '/': // 注意:这里默认除数不为0,实际应用中需添加除数为0的判断 assert(right != 0 && "除数不能为0"); return left / right; default: assert(false && "不支持的运算符"); return 0; } } }; // 测试函数 void testEvalRPN() { Calculator calc; // 测试用例1:1+2-(3*4+5)-7 = -21 vector<string> tokens1 = {"1", "2", "+", "3", "4", "*", "5", "+", "-", "7", "-"}; assert(calc.evalRPN(tokens1) == -21); // 测试用例2:3*(4-5/2) = 3*(4-2) = 6 vector<string> tokens2 = {"3", "4", "5", "2", "/", "-", "*"}; assert(calc.evalRPN(tokens2) == 6); // 测试用例3:100/25 = 4 vector<string> tokens3 = {"100", "25", "/"}; assert(calc.evalRPN(tokens3) == 4); cout << "逆波兰表达式求值测试全部通过!" << endl; } int main() { testEvalRPN(); return 0; }
2.3 代码解析
  1. 数据结构选择:使用stack<int>存储运算数,利用栈的后进先出特性快速获取最近的两个运算数;
  2. 运算符判断:通过isOperator函数判断当前字符串是否为支持的运算符(+、-、*、/);
  3. 运算逻辑:当遇到运算符时,弹出栈顶两个元素,注意先弹出的是右运算数,后弹出的是左运算数(例如a - b,栈中先入 a 再入 b,弹出时先得到 b,再得到 a,计算 a - b);
  4. 异常处理:使用assert断言处理逆波兰表达式格式错误(如运算符过多、运算数过多)和除数为 0 的情况。
2.4 运行结果

编译运行上述代码,最终得到输出如下:

代码语言:javascript

AI代码解释

逆波兰表达式求值测试全部通过!

说明逆波兰表达式的求值逻辑正确,能够处理各种合法的逆波兰表达式。

三、中缀表达式转后缀表达式实现(toRPN)

3.1 功能说明

实现一个函数toRPN,输入为中缀表达式字符串,输出为对应的逆波兰表达式字符串数组。需要处理的主要问题有:运算符优先级对比、括号的递归处理、多位数的读取

www.dongchedi.com/article/7595302803858293310
www.dongchedi.com/article/7595302533728551486
www.dongchedi.com/article/7595303526705152574
www.dongchedi.com/article/7595302533728911934
www.dongchedi.com/article/7595302732916277822
www.dongchedi.com/article/7595300345145164313
www.dongchedi.com/article/7595287730565710361
www.dongchedi.com/article/7595287469617529368
www.dongchedi.com/article/7595289256520663576
www.dongchedi.com/article/7595287092394000920
www.dongchedi.com/article/7595286612611957273
www.dongchedi.com/article/7595285133738410521
www.dongchedi.com/article/7595285905729487384
www.dongchedi.com/article/7595287514580435481
www.dongchedi.com/article/7595285072006382105
www.dongchedi.com/article/7595285719334502936
www.dongchedi.com/article/7595285631619007000
www.dongchedi.com/article/7595277509785453081
www.dongchedi.com/article/7595276630432760345
www.dongchedi.com/article/7595275735409967640
www.dongchedi.com/article/7595277089067549246
www.dongchedi.com/article/7595276413155295769
www.dongchedi.com/article/7595276373905195544
www.dongchedi.com/article/7595274144955499033
www.dongchedi.com/article/7595274423667048984
www.dongchedi.com/article/7595275907217195545
www.dongchedi.com/article/7595274913787953689
www.dongchedi.com/article/7595274806057337368
www.dongchedi.com/article/7595274833727406617
www.dongchedi.com/article/7595255011878208062
www.dongchedi.com/article/7595255232834159166
www.dongchedi.com/article/7595244636982379033
www.dongchedi.com/article/7595246619336000062
www.dongchedi.com/article/7595245102663352894
www.dongchedi.com/article/7595246113737982526
www.dongchedi.com/article/7595238963515146814
www.dongchedi.com/article/7595238605032292888
www.dongchedi.com/article/7595237840809198105
www.dongchedi.com/article/7595237829975212569
www.dongchedi.com/article/7595237024668877336
www.dongchedi.com/article/7594914712018600510
www.dongchedi.com/article/7594913283375907352
www.dongchedi.com/article/7594914016129106456
www.dongchedi.com/article/7594914424213766718
www.dongchedi.com/article/7594913083894891033
www.dongchedi.com/article/7594913119710069310
www.dongchedi.com/article/7594912459706696254
www.dongchedi.com/article/7594911633613390360
www.dongchedi.com/article/7594909036307595800
www.dongchedi.com/article/7594910057444786750
www.dongchedi.com/article/7594909893274927641
www.dongchedi.com/article/7594909974816588350
www.dongchedi.com/article/7594909035217404441
www.dongchedi.com/article/7594908551181615678
www.dongchedi.com/article/7594906883010855486
www.dongchedi.com/article/7594907513641058878
www.dongchedi.com/article/7594905549272285720
www.dongchedi.com/article/7594906861996884505
www.dongchedi.com/article/7594906134906421785
www.dongchedi.com/article/7594905869373096472
www.dongchedi.com/article/7594904114086560281
www.dongchedi.com/article/7594903301414650392
www.dongchedi.com/article/7594901235942228542
www.dongchedi.com/article/7594901805579452953
www.dongchedi.com/article/7594900315275657752
www.dongchedi.com/article/7594899458794799641
www.dongchedi.com/article/7594900266315645465
www.dongchedi.com/article/7594900151853236798
www.dongchedi.com/article/7594898846111580697
www.dongchedi.com/article/7594899021756776984


www.dongchedi.com/article/7594897166766965272
www.dongchedi.com/article/7594897310665245246
www.dongchedi.com/article/7594897192310407705
www.dongchedi.com/article/7594897631617794585
www.dongchedi.com/article/7594896580080435737
www.dongchedi.com/article/7594895704896684568
www.dongchedi.com/article/7594897374330503705
www.dongchedi.com/article/7594895618720449048
www.dongchedi.com/article/7594896034183397912
www.dongchedi.com/article/7594896087656694334

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/14 22:26:40

Unity游戏本地化完全指南:XUnity自动翻译器5大核心技巧

Unity游戏本地化完全指南&#xff1a;XUnity自动翻译器5大核心技巧 【免费下载链接】XUnity.AutoTranslator 项目地址: https://gitcode.com/gh_mirrors/xu/XUnity.AutoTranslator 还在为外语游戏中的生涩对话和复杂菜单而烦恼吗&#xff1f;&#x1f3ae; 语言障碍是否…

作者头像 李华
网站建设 2026/4/8 6:03:57

3个窗口管理痛点,一个AlwaysOnTop解决方案

3个窗口管理痛点&#xff0c;一个AlwaysOnTop解决方案 【免费下载链接】AlwaysOnTop Make a Windows application always run on top 项目地址: https://gitcode.com/gh_mirrors/al/AlwaysOnTop 你是不是也经常遇到这样的场景&#xff1f;正在对照文档编写代码&#xff…

作者头像 李华
网站建设 2026/4/5 18:10:46

视频嗅探神器猫抓:轻松下载网页视频的终极指南

视频嗅探神器猫抓&#xff1a;轻松下载网页视频的终极指南 【免费下载链接】cat-catch 猫抓 chrome资源嗅探扩展 项目地址: https://gitcode.com/GitHub_Trending/ca/cat-catch 还在为无法保存网页视频而烦恼吗&#xff1f;猫抓这款专业的视频嗅探工具正是你需要的解决方…

作者头像 李华
网站建设 2026/4/16 3:39:44

SAM 3实战案例:社交媒体内容自动标记系统构建

SAM 3实战案例&#xff1a;社交媒体内容自动标记系统构建 1. 背景与需求分析 随着社交媒体平台内容的爆炸式增长&#xff0c;图像和视频成为用户表达的主要形式。然而&#xff0c;海量非结构化视觉数据给内容管理、推荐系统和广告投放带来了巨大挑战。传统的人工标注方式效率…

作者头像 李华
网站建设 2026/4/16 3:23:09

网易云音乐NCM加密文件终极解密指南:让音乐重获自由

网易云音乐NCM加密文件终极解密指南&#xff1a;让音乐重获自由 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他设备播放而困扰吗&#xff1f;这款专业的NCM解密工具将彻底解决你的烦恼…

作者头像 李华
网站建设 2026/4/12 0:13:54

终极i茅台自动预约系统:新手必看完整部署指南

终极i茅台自动预约系统&#xff1a;新手必看完整部署指南 【免费下载链接】campus-imaotai i茅台app自动预约&#xff0c;每日自动预约&#xff0c;支持docker一键部署 项目地址: https://gitcode.com/GitHub_Trending/ca/campus-imaotai 还在为i茅台预约烦恼吗&#xf…

作者头像 李华