hdu 1237 简单计算器

一直WA,检查n遍也不知哪错,后来想了想一个99位数加99位数float会爆表,然后换了double就AC了,甚是无语。。。。。。

原来写数据结构作业的代码,一个是求逆波兰式,一个是逆波兰式求解,两个代码一合并就提交了,代码长度比较长一点。。。

思路就是先求逆波兰式,然后逆波兰式求解,C++大法保平安。。。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <ctype.h>
#include <stack>
#include <iostream>
#include <sstream>

using namespace std;

stack<char> s;
stack<double> cal;
string r;
string line;

double atod(char *temp) {   ///手动实现将字符数组转换成double,搞不懂C++库为什么没有atod()
    double r = 0;
    for (int i = 0; temp[i] != '\0'; i++) {
        r *= 10.0;
        r += (double)(temp[i] - '0');
    }
    return r;
}

int main()
{
    while (getline(cin, line)) {    ///读入一行
        if (line.length() == 1) break;    ///对于最后输入0结束标志的判断

        while (!s.empty()) s.pop();   ///栈初始化

        char temp[250];
        stringstream ss;
        ss << line;

        r = "";    ///string初始化
        
        ///开始求逆波兰式并将逆波兰式以string形式存入r
        while (ss >> temp) {
            if (isdigit(temp[0])) {    ///若temp中是数,则直接存入逆波兰式
                r += temp;
                r += ' ';
            } else if (s.empty()) {    ///否则,此时temp中为运算符,若栈为空直接存入栈即可
                s.push(temp[0]);
            } else {                  ///若不为空,当temp中运算符优先级高于栈顶的时,直接存入栈
                if ((s.top() == '+' || s.top() == '-') && (temp[0] == '*' || temp[0] == '/')) {
                    s.push(temp[0]);
                } else {   ///当temp中运算符优先级低于等于栈顶的时,弹出栈顶运算符,
                            ///直到temp中的算符优先级高于栈顶的为止,然后将temp压栈
                    while (!s.empty() && !((s.top() == '+' || s.top() == '-') && (temp[0] == '*' || temp[0] == '/'))) {
                        r += s.top();
                        r += ' ';
                        s.pop();
                    }
                    s.push(temp[0]);
                }
            }
        }
        while (!s.empty()) {    ///将栈中剩下运算符的存入逆波兰式
            r += s.top();
            r += ' ';
            s.pop();
        }
        ///逆波兰式存入完毕
        
        ss.clear();
        ss << r;   ///清空ss后,导入stringstream用于后续解析
        
        while (!cal.empty()) cal.pop();  ///初始化栈用于记录计算的数字
        
        ///开始求逆波兰式
        while (ss >> temp) {     ///将字符串流导入temp,和scanf("%s", temp);一样会跳过空格
            if (isdigit(temp[0])) {
                cal.push(atod(temp));
            } else {
                double sum;
                switch(temp[0]) {
                    case '+': {
                        sum = cal.top();
                        cal.pop();
                        sum += cal.top();
                        cal.pop();
                        break;
                    }
                    case '-': {
                        sum = -cal.top();
                        cal.pop();
                        sum += cal.top();
                        cal.pop();
                        break;
                    }
                    case '*': {
                        sum = cal.top();
                        cal.pop();
                        sum *= cal.top();
                        cal.pop();
                        break;
                    }
                    case '/': {
                        sum = cal.top();
                        cal.pop();
                        sum = cal.top() / sum;
                        cal.pop();
                        break;
                    }
                }
                cal.push(sum);
            }
        }
        ///逆波兰式求解完毕
        
        printf("%.2f\n", cal.top());   ///此时栈顶元素即为算式答案
    }
    return 0;
}


你可能感兴趣的:(算法,栈,简单计算器,逆波兰式,hduoj)