#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")

【思路】

① 设立运算符和运算数两个栈,一个用来存储运算符,另一个用来存储运算数。

② 在运算符栈中放置一个特殊运算符#,其优先级最低。

③ 将表达式尾部添加一个特殊运算符!,其优先级次低。

④ 从左至右依次遍历字符串,若遍历到运算符,则将其与运算符栈的栈顶元素进行比较,若运算符栈的栈顶的优先级小于该运算符,则将该运算符压入运算符栈;否则(若运算符栈的栈顶的优先级大于或等于该运算符),则弹出该栈顶运算符,从运算数栈中依次弹出两次运算数,完成对应的运算后,再将该结果压入运算数栈。

⑤ 若遍历到表达式中的运算数,则直接压入运算数栈。

⑥ 若运算符栈中仅剩两个特殊运算符#$,则表达式运算结束,此时运算数栈中唯一的数字就是表达式的值。

如果带括号则增加两条如下规则:

  1. 遇到左括号"("就直接入栈;
  2. 遇到右括号")"就不断弹出栈顶元素进行运算,知道遇到"("后停止,并将"("出栈;