C++基于调度场算法的基本四则运算计算器 📅 发布时间:2026/7/4 1:09:54 👁️ 浏览次数: 本文为原创技术教程完整代码可直接编译运行适合C入门、数据结构学习者练手参考前言在日常开发与编程学习中四则运算表达式解析是栈数据结构、编译原理词法分析的经典入门实践。我们日常书写的34*2/(1-5)这类中缀表达式符合人类的阅读习惯但对计算机而言存在运算符优先级、括号嵌套等处理难题无法直接顺序计算。本文将基于C实现一套完整的四则运算计算器核心采用调度场算法Shunting-yard Algorithm完成中缀表达式到后缀表达式逆波兰表达式的转换再通过栈结构实现后缀表达式的高效计算。本文代码完整可运行注释清晰可直接复制到本地编译测试也可用于课程作业、个人练手项目。一、核心原理详解1.1 中缀表达式 vs 后缀表达式中缀表达式运算符位于两个操作数中间如12*3需要依赖括号和运算符优先级决定计算顺序人类易读计算机难处理。后缀表达式逆波兰表达式运算符位于两个操作数之后如1 2 3 * 无括号、无优先级歧义严格遵循从左到右的顺序计算完美适配计算机的栈结构处理逻辑。示例中缀表达式34*2/(1-5)转换为后缀表达式为3 4 2 * 1 5 - / 计算顺序完全符合数学规则。1.2 调度场算法中缀转后缀核心调度场算法由计算机科学家Dijkstra提出专门用于中缀表达式到后缀表达式的转换核心通过一个输出队列一个运算符栈实现核心步骤如下从左到右遍历中缀表达式的每个字符若为数字直接加入输出队列若为左括号(直接压入运算符栈若为右括号)将栈顶运算符依次弹出并加入输出队列直到遇到左括号弹出左括号并丢弃不加入输出若为运算符将栈中优先级大于等于当前运算符的栈顶元素依次弹出并加入输出队列直到栈空或遇到左括号再将当前运算符压入栈遍历结束后将栈中剩余的所有运算符依次弹出加入输出队列。1.3 后缀表达式的计算逻辑后缀表达式的计算完全依赖栈结构步骤极简且无歧义从左到右遍历后缀表达式的每个token数字/运算符若为数字直接压入数字栈若为运算符连续弹出栈顶两个元素先弹出的为右操作数b后弹出的为左操作数a执行a 运算符 b将计算结果压回栈中遍历结束后栈中仅剩的一个元素就是表达式的最终计算结果。关键提醒减法、除法对操作数顺序敏感必须严格遵循左操作数 运算符 右操作数的顺序否则会出现计算错误。二、代码模块逐行详解2.1 头文件与全局配置首先引入所需的标准库并定义运算符优先级映射表使用unordered_map实现O(1)时间复杂度的优先级查询const修饰保证全局只读避免误修改。#includeiostream#includestack// 栈容器用于运算符暂存与数字计算#includestring// 字符串处理存储表达式#includeunordered_map// 无序映射存储运算符优先级#includesstream// 字符串流用于后缀表达式的token分割// 运算符优先级映射表数字越大优先级越高conststd::unordered_mapchar,intPRECENCE{{*,2},// 乘除优先级高于加减{/,2},{,1},{-,1},{(,0}// 左括号优先级最低仅作为边界标识};2.2 中缀表达式转后缀表达式实现核心函数tolastStr完整实现调度场算法同时解决了新手常见的多位数拆分、栈空访问崩溃、括号处理异常等问题。核心步骤遍历中缀表达式若为数字则直接加入输出队列若为符号则先与符号栈栈顶循环判断优先级将小于等于其的元素依次出栈进入输出队列最后再入栈特殊的遇到右括号时直接将栈顶元素循环出栈直到遇到左括号最后遍历完成后将符号栈中元素全部出栈进入输出队列这个输出队列就是转化的后缀表达式。std::stringtolastStr(std::string str){std::stackcharop_stack;// 运算符栈临时存放运算符std::string lastStr;// 输出队列存储最终的后缀表达式// 遍历输入的中缀表达式for(constchari:str){// 1. 处理数字直接加入输出队列if(0ii9){lastStr.push_back(i);}// 2. 处理非数字字符运算符、括号else{// 给数字加空格分隔解决多位数拆分问题如123不会被拆成1、2、3if(!lastStr.empty()lastStr.back()! ){lastStr.push_back( );}// 2.1 处理左括号直接入栈if(i(){op_stack.push(i);}// 2.2 处理右括号弹出运算符直到左括号elseif(i)){while(!op_stack.empty()op_stack.top()!(){lastStr.push_back(op_stack.top());lastStr.push_back( );op_stack.pop();}// 弹出左括号并丢弃不加入输出队列if(!op_stack.empty()){op_stack.pop();}}// 2.3 处理四则运算符按优先级处理栈else{// 弹出栈中优先级当前运算符的元素直到栈空/遇到左括号// 使用at()而非[]避免不存在的运算符导致未定义行为while(!op_stack.empty()op_stack.top()!(PRECENCE.at(i)PRECENCE.at(op_stack.top())){lastStr.push_back(op_stack.top());lastStr.push_back( );op_stack.pop();}// 当前运算符入栈op_stack.push(i);}}}// 遍历结束弹出栈中剩余的所有运算符while(!op_stack.empty()){if(!lastStr.empty()lastStr.back()! ){lastStr.push_back( );}lastStr.push_back(op_stack.top());op_stack.pop();}returnlastStr;}关键细节说明多位数处理通过空格分隔数字与运算符后续通过 stringstream 可正确拆分多位数解决了新手代码仅支持个位数的痛点健壮性优化所有栈操作前都做了 !op_stack.empty() 非空判断避免栈空访问导致的程序崩溃安全访问使用 PRECENCE.at(i) 而非 [] 访问优先级 at() 会做边界检查遇到非法运算符时抛出异常避免未定义行为括号处理严格遵循调度场算法规则右括号仅弹出到左括号左括号不会进入输出队列。2.3 后缀表达式计算实现函数 result_math 实现后缀表达式的计算通过 stringstream 自动分割空格分隔的token逻辑清晰适配多位数场景。利用流的自动空白字符分割判断快速切分获取 token 之后再逐一判断 token若为数字则直接入栈若为符号则依次取出栈两个数字进行计算后出栈的为左计算单元最后将计算完成的结果入栈以此类推到最后留在栈中的一个元素就是计算结果。intresult_math(std::string str){std::stackintnum_stack;// 数字栈存储操作数与中间结果std::stringstreamss(str);// 字符串流自动按空格分割tokenstd::string token;// 遍历每个tokenwhile(sstoken){// 1. 处理运算符弹出两个操作数计算if(token||token-||token*||token/){// 注意顺序先弹出的是右操作数b后弹出的是左操作数aintbnum_stack.top();num_stack.pop();intanum_stack.top();num_stack.pop();// 按运算符执行计算结果入栈if(token)num_stack.push(ab);elseif(token-)num_stack.push(a-b);elseif(token*)num_stack.push(a*b);elseif(token/)num_stack.push(a/b);// 整数除法向零取整}// 2. 处理数字转为int后入栈else{num_stack.push(std::stoi(token));}}// 栈中剩余的唯一元素即为最终结果returnnum_stack.top();}2.4 主函数入口逻辑主函数实现用户输入、表达式转换、结果输出的完整流程增加了基础的输入合法性判断。intmain(intargc,char*argv[]){std::cout请输入计算表达式 :std::endl;std::string midStr,lastStr;std::cinmidStr;// 基础输入校验空输入直接退出if(midStr.size()0)return1;// 中缀转后缀lastStrtolastStr(midStr);// 输出中间结果与最终计算结果std::cout后缀表达式lastStrstd::endl;std::cout计算结果result_math(lastStr)std::endl;return0;}三、当前版本局限与扩展优化方向4.1 当前版本局限仅支持正整数的四则运算不支持浮点数、负数输入仅支持 、-、*、/ 四个基础运算符不支持取模、幂运算等异常处理不完善除零错误、括号不匹配、非法字符输入会导致程序异常仅支持整数除法向零取整无小数精度处理。4.2 进阶扩展优化方案支持浮点数运算将操作数类型从 int 改为 double 数字转换函数从 std::stoi 改为 std::stod 适配小数输入与浮点计算支持负数处理增加负号判断逻辑识别表达式开头的 - 、括号后的 - 为负号而非减法运算符完善异常处理增加 try-catch 异常捕获处理除零错误、括号不匹配、非法字符、表达式格式错误等场景提升程序健壮性扩展运算符支持新增取模 % 、幂运算 ^ 、开方等运算符更新优先级映射表与计算逻辑五、总结本文通过C完整实现了一套基于调度场算法的四则运算计算器核心覆盖了栈数据结构的经典应用、调度场算法的工程实现、表达式解析的核心逻辑三大核心知识点。该项目是数据结构与算法入门的绝佳练手案例既可以帮助新手理解栈的应用场景也可以作为编译原理词法分析的入门实践。
【2026最新】大模型AI产品经理学习路线:从零基础到精通,大模型产品经理的进阶学习路线图! 随着人工智能技术的发展,尤其是大模型(Large Model)的兴起,越来越多的企业开始重视这一领域的投入。作为大模型产品经理,你需要具备一系列跨学科的知识和技能,以便有效地推动产品的开发、优化和市场化。以下… 2026/5/17 10:20:59
零跑汽车再度冠名浙江FC 共战2026新赛季 3月8日,零跑汽车与浙江职业足球俱乐部(简称浙江FC)联合宣布:零跑汽车将继续作为浙江FC主赞助商,与浙江俱乐部绿城队共同迎接2026赛季中超联赛及足协杯赛事。同时,零跑汽车成为浙江职业足球俱乐部官方指定用… 2026/5/17 10:20:59
洛谷 P1162 填涂颜色 洛谷 P1162 填涂颜色P1162 填涂颜色这个题,一开始看着挺懵,后来用 DFS一拆解,发现核心逻辑其实超简单!今天就把这个题的解题思路和代码分享给大家,新手也能轻松看懂。先说说题目要求:给一个 nn 的方阵&… 2026/5/17 9:52:33
OpenClaw开源金融数据分析工具链实战指南 1. 项目背景与核心价值OpenClaw作为一款开源的金融数据分析工具链,正在改变传统金融机构处理海量市场数据的方式。我第一次接触这个工具是在2021年参与某量化对冲基金的数据基础设施升级项目,当时团队需要处理来自全球37个交易所的实时tick数据ÿ… 2026/7/4 1:09:11
AI智能体能力分级与开发实战指南 1. AI智能体能力分级:从基础工具到数字员工第一次接触AI智能体这个概念时,我正为一个电商客户设计客服机器人。当时只是简单调用API返回预设回答,直到看到Level 1到Level 5的分级框架,才真正理解智能体的进化路径。这个分级体系就… 2026/7/4 1:07:10
AI编程的四种形态与Agent模式实践指南 1. AI编程的四种形态解析在技术社区讨论AI编程时,我们经常发现参与者对"AI编程"的理解存在显著差异。就像木匠讨论工具时,有人指锤子,有人谈电锯,虽然都属于工具范畴,但适用场景和效果截然不同。目前AI编程主… 2026/7/4 1:07:10
企业级AI应用工程化实战:基于Agent与Harness Engineering的智能数据分析助手构建 🚀 30款热门AI模型一站整合,DeepSeek/GLM/Claude 随心用,限时 5 折。 👉 点击领海量免费额度 如果你正在寻找一个能真正将 AI 大模型能力“工程化”落地到企业业务中的实战方案,而不是停留在 API 调用的玩具 demo&a… 2026/7/4 1:05:10
Java工程师转型AI开发:RAG与Agent技术实战指南 1. 职业转型全景:程序员如何切入AI应用开发领域作为一名从Java转型到AI应用开发的工程师,我深刻理解这个过程中的困惑与挑战。2026年的AI应用开发领域已经形成了清晰的职业分工,不同背景的开发者都能找到适合自己的切入点。1.1 六大AI工程师方… 2026/7/4 1:01:10
Claude Code智能编程助手实战优化指南 1. 项目概述作为一名长期与AI编程助手打交道的开发者,我深刻理解掌握像Claude Code这样的高级AI编程工具需要经历的学习曲线。Claude Code作为新一代智能编程助手,其核心价值在于理解开发者意图、生成高质量代码并提供专业级调试建议。但在实际使用过程中… 2026/7/4 1:01:10
STM32F745VG与MC6470 IMU的高性能姿态控制系统设计 1. MC6470与STM32F745VG的黄金组合解析在工业自动化和机器人控制领域,传感器与微控制器的协同工作能力直接决定了系统的响应速度和定位精度。MC6470作为一款6自由度惯性测量单元(6DOF IMU),与STM32F745VG这款基于ARM Cortex-M7内核的高性能微控制器组合&… 2026/7/4 0:00:28
Playwright自动化测试实战:从零搭建现代Web测试框架 1. 项目概述:为什么是 Playwright?如果你正在为现代 Web 应用的自动化测试头疼,尤其是面对那些充斥着动态加载、复杂交互的单页应用(SPA),那么 Playwright 的出现,很可能就是你的解药。我接触过… 2026/7/4 0:00:28
终极指南:如何将JSXBIN二进制文件转换为可读JSX源代码 终极指南:如何将JSXBIN二进制文件转换为可读JSX源代码 【免费下载链接】jsxbin-to-jsx-converter JSXBin to JSX Converter written in C# 项目地址: https://gitcode.com/gh_mirrors/js/jsxbin-to-jsx-converter 你是否曾经面对过Adobe产品的JSXBIN文件感到… 2026/7/4 0:02:28