九度OJ 1019

66 篇文章 1 订阅
题目描述:
    读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。
输入:
    测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。当一行中只有0时输入结束,相应的结果不要输出。
输出:
    对每个测试用例输出1行,即该表达式的值,精确到小数点后2位。
样例输入:
1 + 2
4 + 2 * 5 - 7 / 11
0
样例输出:
3.00
13.36

解析:几乎所有数据结构的书上在讲栈的应用的时候,肯定会讲这个简单计算器的实现。没错,这个表达式的计算充分考察了我们对于栈的理解。
因为之前做过一个类似的表达式的计算,所以这个题目做起来还是一次性A的。
首先建立两个栈,一个字符栈,用来保存运算符;另一个数字栈,用来保存数字。注意这里保存的数字应该是 double型的,因为结果输出要保留两位小数。还有一点要注意的是,输入的数字可能是多位的,所以这里只能一位一位扫描,遇到空格则跳过,不能直接i=i+2。然后遇到后面还是数字的情况就将前面的值乘以10加上当前的数字即可。
从左往右扫描,遇到数字放入数字栈,遇到字符放入字符栈。如果当前字符的优先级比栈顶符号的优先级要大,则直接入栈。否则从数字栈弹出两个数字,从字符栈弹出一个运算符,进行运算后,将结果压入数字栈。之后还要进行字符优先级的判断,直到当前字符的优先级大于栈顶符号的优先级。最后把当前字符压入字符栈内。
全部扫描之后,还要进行最后栈内的运算。如果字符栈不空,不断的弹出两个数字栈内的元素和栈顶运算符,运算之后结果入栈。最后输出数字栈内的唯一的一个元素,就是要求的结果。注意输出的结果格式就行。
#include <iostream>
#include <stack>
#include <iomanip>
using namespace std;

int get_priority(char c){
    if(c == '+' || c == '-')
        return 1;
    if(c == '*' || c == '/')
        return 2;
    else
        return 0;
}

int main(){
    stack<char>char_s;
    stack<double>num_s;
    string str;
    while(getline(cin,str)){
        if(str == "0")
            break;
        for(int i=0;i<str.length();i++){
            if(str[i] == ' ')
                continue;
            int num = 0;
            int j = i;
            if(str[j]>='0' && str[j]<='9'){
                while(str[j]>='0' && str[j]<='9'){
                    num = num*10 + (str[j] - '0');
                    j++;
                }
                num_s.push(num);
                i = j-1;
            }
            else{
                if(char_s.empty()){
                    char_s.push(str[i]);
                    continue;
                }
                if(get_priority(str[i]) > get_priority(char_s.top()))
                   char_s.push(str[i]);
                else{
                    do{
                        double result;
                        double a = num_s.top();
                        num_s.pop();
                        double b = num_s.top();
                        num_s.pop();
                        char c = char_s.top();
                        char_s.pop();
                        if(c == '+')    result = b + a;
                        if(c == '-')    result = b - a;
                        if(c == '*')    result = b * a;
                        if(c == '/')    result = b / a;
                        num_s.push(result);
                        if(char_s.empty())
                            break;
                    }while(get_priority(str[i]) <= get_priority(char_s.top()));
                    char_s.push(str[i]);
                }
            }
        }
        while(!char_s.empty()){
            double result;
            double a = num_s.top();
            num_s.pop();
            double b = num_s.top();
            num_s.pop();
            char c = char_s.top();
            char_s.pop();
            if(c == '+')    result = b + a;
            if(c == '-')    result = b - a;
            if(c == '*')    result = b * a;
            if(c == '/')    result = b / a;
            num_s.push(result);
        }
        cout<<fixed<<setprecision(2)<<num_s.top()<<endl;
        //printf("%.2f",num_s.top());
        num_s.pop();
    }
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值