简单计算器(栈)
简单计算器
开始复习栈,这个题感觉见得很多,各种各样的,但是核心思路就是把中缀表达式转化为后缀表达式,我们老师说这个东西也叫作中序二叉树转后序二叉树。大概实现的方式就是用栈来实现
最开始感觉没啥思路,因为之前一直都不会这种题 论为什么我这么菜,之前没有好好学过栈,知道了STL中有stack后还是方便很多
第一次做的思路就是直接对操作数和操作运算符入栈,挨着挨着算,编了一通之后交上去全WA,因为这样做的话是没有考虑到一些复杂运算(优先级问题)。这样的话,我们就不能边读入边处理,应该整个输入之后,转为后缀表达式
这是大概的思路,但是中间的一些实现方法中有一些细节。因为涉及到整行读入,用string的话应该用getline,但是string的比较函数我个人是不知道的,所以在判断等于0结束的情况时,还需要判断长度。用char的话,整行读入用gets,有一个strcmp比较函数,可以直接使用,挺方便的。对于优先级的话,写个函数就行了
#include<bits/stdc++.h>
using namespace std;
int yxj(char q){ //处理操作符优先级
if(q=='*'||q=='/') return 999;
else if(q=='+'||q=='-') return 111;
return 0;
}
int main(){
stack<double> num;
stack<char> op;
char a[205];
int i,t;
while(gets(a)!=NULL&&strcmp("0",a)){ //判断是否结束输入
i=t=0; //t用来存储每一个数字,i表示a[i]
while(a[i]||!op.empty()){
if(a[i]==' ') i++;
else if(a[i]>='0'&&a[i]<='9'){ //存数字
t=t*10+a[i]-'0';
i++;
if(!(a[i]>='0'&&a[i]<='9')){
num.push(t);
t=0;
}
}else if(op.empty()||yxj(a[i])>yxj(op.top())){ //优先级较高就先存
op.push(a[i]);
i++;
}else{ //算答案
double le=num.top();
num.pop();
double ri=num.top();
num.pop();
if(op.top()=='*') num.push(le*ri);
if(op.top()=='/') num.push(ri/le);
if(op.top()=='+') num.push(le+ri);
if(op.top()=='-') num.push(ri-le);
op.pop();
}
}
printf("%.2lf\n",num.top());
}
return 0;
}
当然,不止有栈的做法,同机房的大佬也有用队列做的,大家可以去看看,队列做法