#include <iostream>
#include<stack>
#include <string>
using namespace std;
//返回优先级,优先级顺序:# ! + - * /
int priority(char c){
if(c=='#')return 0;
else if (c=='!')return 1;
else if (c=='+' || c=='-')return 2;
else return 3;
}
//计算函数
float com(float n1,char op,float n2){
if(op=='+') return n1+n2;
if(op=='-') return n1-n2;
if(op=='*') return n1*n2;
if(op=='/') return n1/n2;
return 0;
}
//注意:所有数字都要使用float类型
float result(string str){
stack<float> nums;
stack<char> ops;
ops.push('#');
for(int i=0;i<str.size();i++){
char c = str[i];
if(c==' ')continue;//跳过字符串中的空格
if(c-'0'<=9 && c-'0'>=1){
float num=c-'0';
//这个while循环用来处理大于10的多位数
while(str[i+1]-'0'<=9 && str[i+1]-'0'>=0){
int tem=str[i+1]-'0';
num=num*10+tem;
i++;
}
nums.push(num);
}else {
if(priority(c)>priority(ops.top())){
//只有当前运算符优先级大于栈顶运算符时,才入栈;小于等于时都要先出栈计算;
ops.push(c);
}else {
//小于等于时都要先出栈计算;
char op = ops.top(); ops.pop();
float n1=nums.top(); nums.pop();
float n2=nums.top();nums.pop();
float k = com(n2, op, n1);
nums.push(k);
i--; //这里i--抵消for循环中的i++;继续遍历当前这个因为优先级小而未入栈的运算符;
}
}
}
return nums.top(); //遍历完后,数字栈中就只剩下一个数,就是最终结果,返回即可;
}
int main() {
string str;
while (getline(cin,str)) {
if(str=="0"){
break;
}
float res=result(str+"!");
printf("%.2f\n",res); //%.2f保留两位小数
}
}
// long long 64位输出请用 printf("%lld")
【思路】
① 设立运算符和运算数两个栈,一个用来存储运算符,另一个用来存储运算数。
② 在运算符栈中放置一个特殊运算符#,其优先级最低。
③ 将表达式尾部添加一个特殊运算符!,其优先级次低。
④ 从左至右依次遍历字符串,若遍历到运算符,则将其与运算符栈的栈顶元素进行比较,若运算符栈的栈顶的优先级小于该运算符,则将该运算符压入运算符栈;否则(若运算符栈的栈顶的优先级大于或等于该运算符),则弹出该栈顶运算符,从运算数栈中依次弹出两次运算数,完成对应的运算后,再将该结果压入运算数栈。
⑤ 若遍历到表达式中的运算数,则直接压入运算数栈。
⑥ 若运算符栈中仅剩两个特殊运算符#和$,则表达式运算结束,此时运算数栈中唯一的数字就是表达式的值。
如果带括号则增加两条如下规则:
- 遇到左括号"("就直接入栈;
- 遇到右括号")"就不断弹出栈顶元素进行运算,知道遇到"("后停止,并将"("出栈;

京公网安备 11010502036488号