每日一题 KY129 简单计算器

本文介绍了一种利用C++编程实现的方法,通过栈数据结构处理只包含加号、减号、乘号和除号的非负整数表达式,解析输入并计算结果,保留两位小数。
摘要由CSDN通过智能技术生成

读入一个只包含 +, -, *, 的非负整数计算表达式,计算该表达式的值。

输入描述:
    测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。当一行中只有0时输入结束,相应的结果不要输出。


 

输出描述:
    对每个测试用例输出1行,即该表达式的值,精确到小数点后2位。

示例1

输入

1 + 2
4 + 2 * 5 - 7 / 11
0

输出

3.00
13.36
#include <iostream>
#include <string>
#include <stack>
#include <map>
using namespace std;
//表达式解析
//遍历整个字符串 string->int
//两个栈 分别存中间结果,运算符
//newoper优先级低或相等 栈内运算符元素及数字弹栈 之后再将低运算符压入栈中
// newoper优先级高压栈
int main() {
    char buf[300];
    //优先级 *、/、+、—、$
    map<char,int> priority={ {'$',0},
                              {'+',1},{'-',1},
                              {'*',2},{'/',2}
                            };
    while (fgets(buf,300,stdin)!=NULL){//需要读入空格,不能用scanf
        string expr=buf;//转为字符串
        expr.pop_back();//去掉换行
        if(expr=="0"){
            break;//输入0 整个结束
        }
        expr.push_back('$');//补充虚拟终止符
        string num;//字符串转为数字
        stack<double> numstack;//存中间结果
        stack<char> operstack;//存运算符
        //遍历字符串
        for(unsigned i=0;i<expr.size();i++){
            if(expr[i]>='0' && expr[i]<='9'){//是数字 放入string类型的num
                num.push_back(expr[i]);
            }else if(expr[i]==' '){//是空格
                if(num!=""){
                    numstack.push(stod(num));//string->int 转换压入栈中
                    num="";
                }
            }else{//+-*/$
                if(expr[i]=='$'){
                    if(num!=""){
                        numstack.push(stod(num));
                        num="";
                    }
                }
                //运算符优先级低 栈非空 栈顶元素>=新运算符
                while (!operstack.empty() && priority[operstack.top()]>=priority[expr[i]]){
                    char oper=operstack.top();
                    operstack.pop();//栈顶元素弹出
                    double rhs=numstack.top();//数字栈弹出栈顶元素 为右操作数
                    numstack.pop();
                    double lhs=numstack.top();//数字栈弹出栈顶元素 为右操作数
                    numstack.pop();
                    //运算中间结果
                    switch (oper) {
                        case '+':
                            numstack.push(lhs + rhs);
                            break;
                        case '-':
                            numstack.push(lhs - rhs);
                            break;
                        case '*':
                            numstack.push(lhs * rhs);
                            break;
                        case '/':
                            numstack.push(lhs / rhs);
                            break;
                    }
                }
                //优先级更高的已运算完成
                //将高或低运算符压入栈中
                operstack.push(expr[i]);
            }

        }
        printf("%.2lf\n",numstack.top());//输出小数点两位.2 double是lf

    }
    return 0;
}

  • 7
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值