简单计算器(王道)

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

using namespace std;
char str[220];//保存表达式字符串
int mat[][5] = {//优先级矩阵,0号为表达式首尾的标记运算符,1号为+,2号为-,3号为*,4号为/
    1,0,0,0,0,
    1,0,0,0,0,
    1,0,0,0,0,
    1,1,1,0,0,
    1,1,1,0,0,
};
stack<int> op;//运算符栈,保存运算符编号
stack<double> in;//数字栈
void getOp(bool &reto, int &retn, int &i){
    /**获得下一个元素,如果是运算符,reto为true,编号保存在引用变量retn中;
    **如果是数字,值保存在retn中,i表示遍历到的字符串下标
    */
    if(i == 0 && op.empty() == true){
        //此时遍历字符串第一个字符,且运算符栈为空,人为添加编号为0的标记字符
        reto = true;
        retn = 0;
        return;
    }
    if(str[i] == 0){
        //遍历字符为空字符,表示字符串已经被遍历完
        reto = true;
        retn = 0;
        return;
    }
    if(str[i] >= '0' && str[i] <= '9'){
        //若当前字符为数字,返回为数字
        reto = false;
        retn = 0;
        for(;str[i] != ' ' && str[i] != 0;i++){
            retn *= 10;
            retn += str[i] - '0';
        }
        if(str[i] == ' ')
            //如果后面是空格,字符串没遍历完,继续向后遍历
            i++;
        return;
    }else{
        //当前字符为操作符
        reto = true;
        if(str[i] == '+')
            retn = 1;
        else if(str[i] == '-')
            retn = 2;
        else if(str[i] == '*')
            retn = 3;
        else if(str[i] == '/')
            retn = 4;
        i += 2;//跳过字符和后面的空格
        return;
    }
}
int main()
{
    while(gets(str)){
        if(str[0] == '0' && str[1] == 0)
            break;//输入只有一个0,退出
        bool retOp;
        int retNum;
        int index = 0;
        while(!op.empty())
            op.pop();//清空字符栈
        while(!in.empty())
            in.pop();//清空数字栈
        while(true){//循环遍历表达式字符串
            getOp(retOp,retNum,index);//获取表达式下一个元素
            if(retOp == false)//数字
                in.push((double)retNum);
            else{//运算符
                double tmp;
                if(op.empty() == true || mat[retNum][op.top()] == 1)
                    op.push(retNum);//运算符栈为空或当前遍历到的运算符优先级比栈顶运算符大,将该运算符压入运算符堆栈
                else{
                    while(mat[retNum][op.top()] == 0){//当前运算符优先级低
                        int ret = op.top();
                        op.pop();
                        double b = in.top();
                        in.pop();
                        double a = in.top();
                        in.pop();
                        if(ret == 1)
                            tmp = a+b;
                        else if(ret == 2)
                            tmp = a-b;
                        else if(ret == 3)
                            tmp = a*b;
                        else if(ret == 4)
                            tmp = a/b;
                        in.push(tmp);
                    }
                    op.push(retNum);
                }

            }
            if(op.size() == 2 && op.top() == 0)
            //运算符栈只有两个运算符,且栈顶运算符为0,表示表达式求值结束(这两个运算符分别是开头和结尾的0)
                break;
        }
        printf("%.2f\n",in.top());
    }
    return 0;
}

 

posted @ 2018-03-12 10:14  Shaw_喆宇  阅读(258)  评论(0编辑  收藏  举报