栈实现表达式求值
作者:@kuaiquxie
作者的github:https://github.com/bitebita
本文为作者原创,如需转载,请注明出处:https://www.cnblogs.com/dzwj/p/15659484.html
栈实现表达式求值
使用键盘输入数学表达式(含数字,四种运算符+、-、、/和小括号,其中运算数都是一位数(0~9)),将数学表达式转化成后缀表达式输出,利用后缀表达式求表达式的值并输出。
输入格式:
输入正确的表达式(可以有空格)后回车,得到后缀表达式和结果。输入括号缺失的表达式,输出"ERROR:缺少括号"。输入两个除括号外运算符连续的表达式,输出"ERROR:表达式缺操作数"。
输出格式:
请在这里描述输出格式。例如:对每一组输入,在一行中输出A+B的值。
输入样例:
在这里给出一组输入。例如:
5*(8-(3+2))
结尾无空行
输出样例:
在这里给出相应的输出。例如:
5832+-* 15
结尾无空行
代码如下:
#include<stdio.h> #include<iostream> #include<stack> #include<string> #include <math.h> using namespace std; stack<int> MoveIn; stack<char> CharStack; string fixStr = ""; void IntoPost(string inStr); bool isPush(char pre, char late); void Calculate(char np); void CalFix(); void pushChar(char np); string format(string inStr) { //解决(-1+2)负数报错问题 for (int i = 0; i < inStr.length(); i++) //即在 -1 前面加一个0 变成 0-1 即可 if (inStr[i] == '-') if (i == 0) inStr.insert(0, 1, '0'); else if (inStr[i - 1] == '(') inStr.insert(i, 1, '0'); return inStr; } int main(){ string inStr; getline(cin, inStr); //使用getline 解决字符串录入遇空格结束的问题 类似 ( a + b ) 只写入了 ( 的 inStr = format(inStr); int i=0; int K_num=0; int K_1=0; int K_2=0; while(inStr[i]!='\0') { if(inStr[i]=='('||inStr[i]==')') { K_num++; } if(inStr[i]=='+'||inStr[i]=='-'||inStr[i]=='*'||inStr[i]=='/') { if(inStr[i+1]=='+'||inStr[i+1]=='-'||inStr[i+1]=='*'||inStr[i+1]=='/') { K_1=1; printf("ERROR:表达式缺操作数"); } } i++; } if(K_num%2!=0) { K_2=1; printf("ERROR:缺少括号"); } if((K_1==0)&&(K_2==0)) { IntoPost(inStr);cout<<fixStr<<endl; CalFix(); } return 0; } void IntoPost(string inStr) { //前缀转后缀 for (int i = 0; i < inStr.length(); i++) { switch (inStr[i]) { case ' ': break; case '+':pushChar('+'); break; case '(':CharStack.push('('); break;//遇前括号直接入栈 case ')': //遇后括号弹出所有至上一个括号 while (CharStack.top() != '(') { fixStr += CharStack.top(); CharStack.pop(); } CharStack.pop(); break; case '/':pushChar('/'); break; case '*':pushChar('*'); break; case '-':pushChar('-'); break; case '^':pushChar('^'); break; default: fixStr += inStr[i]; break; //数字直接输出 } } while (!CharStack.empty()) { //整式尾部时弹出所有站内符号 fixStr += CharStack.top(); CharStack.pop(); } } void pushChar(char np) { //运算符出栈 if (!CharStack.empty()){ while (!CharStack.empty() && isPush(CharStack.top(), np)) { fixStr += CharStack.top(); //判断优先级 CharStack.pop(); } CharStack.push(np); } else CharStack.push(np); } bool isPush(char pre, char late) { //优先级比较 if (late == '^') if (pre == '^') return true; else return false; if (late == '*' || late == '/') if (pre == '^' || pre == '*' || pre == '/') return true; else return false; if (late == '+' || late == '-') if (pre == '(') return false; else return true; return false; } void CalFix() { //后缀表达式计算 for (int i = 0; i < fixStr.length(); i++) { switch (fixStr[i]) { case '+':Calculate('+'); break; case '/':Calculate('/'); break; case '*':Calculate('*'); break; case '-':Calculate('-'); break; case '^':Calculate('^'); break; case ' ': break; default: int a; a = (int)(fixStr[i] - 48); MoveIn.push(a); break; } } cout << MoveIn.top(); } void Calculate(char np) { //弹出两个栈内数运算后再压进栈 int pre, late; late = MoveIn.top(); MoveIn.pop(); pre = MoveIn.top(); MoveIn.pop(); switch (np) { case '+':MoveIn.push(pre + late); break; case '/':MoveIn.push(pre / late); break; case '*':MoveIn.push(pre * late); break; case '-':MoveIn.push(pre - late); break; case '^':MoveIn.push(pow(pre,late)); break; default: break; } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)
· AI 智能体引爆开源社区「GitHub 热点速览」