cpp
#include<bits/stdc++.h>
using namespace std;
typedef char elemtype;
typedef struct node{
elemtype data;
struct node* next;
}LinkStack;
typedef struct node1{
int data;
struct node1* next;
}LinkStack1;
bool push(LinkStack **top, elemtype e);
bool pop(LinkStack **top, elemtype &e);
bool pushi(LinkStack1 **top, int e);
bool popi(LinkStack1 **top, int &e);
int cmpoptr(char a,char b);
int op(int a,int b,char optr);
int main(){
//给定含+-*/(),数字的字符串,用#表示结束,用O(n)算出表达式结果
char str[1001]={'\0'},abandon;
LinkStack *optrtop=NULL;
LinkStack1 *opndtop=NULL;
push(&optrtop,'#');
scanf("%1000s",str);
for(int i=0;str[i];i++){
int num=0,flag=0,a,b,result;//strcmp('0',str[i])<=0&&strcmp(str[i],'9')<=0
for(;'0'<=str[i]&&str[i]<='9';i++,flag=1){
num*=10;
num+=(str[i]-'0');
}
if(flag){
i--;
pushi(&opndtop,num);
}
else{
if(cmpoptr(optrtop->data,str[i])<0){
push(&optrtop,str[i]);
}
else if(cmpoptr(optrtop->data,str[i])==0)pop(&optrtop,abandon);
else{
char optr;
popi(&opndtop,b);
popi(&opndtop,a);
pop(&optrtop,optr);
result=op(a,b,optr);
pushi(&opndtop,result);
i--;
}
}
}
int final;
popi(&opndtop,final);
printf("the result is %d",final);
return 0;
}
int cmpoptr(char a,char b){
//默认ab只可能为+-*/()#
if(a=='+'||a=='-'){
if(b=='*'||b=='/'||b=='(')return -1;
else return 1;
}
else if(a=='*'||a=='/'){
if(b=='(')return -1;
else return 1;
}
else if(a=='('){
if(b==')')return 0;
else return -1;
}
else if(a==')')return 1;
else return -1;//a=='#'
}
int op(int a,int b,char optr){
if(optr=='+')return a+b;
else if(optr=='-')return a-b;
else if(optr=='*')return a*b;
else if(optr=='/')return a/b;//就整数除法吧,偷懒不管了
else exit(1);//其余情况不受理
}
bool push(LinkStack **top, elemtype e){
LinkStack *tem=(LinkStack*)malloc(sizeof(LinkStack));
if(!tem)exit(1);
tem->data=e;
tem->next=*top;
*top=tem;
return 1;
}
bool pop(LinkStack **top, elemtype &e){
if(!*top)exit(1);
LinkStack *tem=(*top)->next;
e=(*top)->data;
free(*top);
*top=tem;
return 1;
}
bool pushi(LinkStack1 **top, int e){
LinkStack1 *tem=(LinkStack1*)malloc(sizeof(LinkStack1));
if(!tem)exit(1);
tem->data=e;
tem->next=*top;
*top=tem;
return 1;
}
bool popi(LinkStack1 **top, int &e){
if(!*top)exit(1);
LinkStack1 *tem=(*top)->next;
e=(*top)->data;
free(*top);
*top=tem;
return 1;
}
代码思路
核心算法
使用双栈法(运算符栈 + 操作数栈)实现中缀表达式求值,基于运算符优先级进行比较和计算。
执行流程
-
初始化:运算符栈压入'#'作为结束标志
-
扫描表达式:
-
遇到数字:解析完整数字后压入操作数栈
-
遇到运算符:
-
优先级高于栈顶:压入运算符栈
-
优先级等于栈顶(括号匹配):弹出左括号
-
优先级低于栈顶:弹出运算符和两个操作数进行计算,结果压回操作数栈
-
-
代码用法
输入格式
text
表达式#
示例:2*(3+4)/5#
输出
直接输出表达式计算结果
功能特点
-
支持的运算符 :
+,-,*,/,(,) -
数字处理:多位数自动解析
-
优先级规则:
-
*,/>+,- -
括号改变优先级
-
-
错误处理:内存分配失败时直接退出
代码限制
-
整数除法:使用C++整数除法,会截断小数部分
-
错误处理简单:遇到非法表达式直接崩溃,无友好提示
-
输入长度限制:最多1000个字符
-
运算符限制:不支持求模、幂运算等其他运算符
-
负数处理 :不支持负号作为一元运算符(如
-5) -
空格处理:输入中不能包含空格
-
结束标志 :必须用
#结束表达式
潜在改进方向
-
添加表达式合法性检查
-
支持浮点数运算
-
增加错误信息提示
-
支持更多运算符和函数
-
处理一元负号
-
移除必须的
#结束符