九度OJ 1101 表达式求值(栈的应用)

原题地址:http://ac.jobdu.com/problem.php?pid=1101

题目描述:

对于一个不存在括号的表达式进行计算

输入:

存在多种数据,每组数据一行,表达式不存在空格

输出:

输出结果

样例输入:
6/2+3+3*4
样例输出:
18
来源:

2010年上海交通大学计算机研究生机试真题


本题和之前一篇博客《九度OJ 1019简单计算器》几乎一致,但是当时写完1019后再次做这个题,其实还有另外的解法。由于只有四则运算,所以不用拘泥于运算符的优先级,说白了就是乘除法比加减法先算而已,所以换一种思路实现。

依然是从左到右遍历字符串(为输入串加上终结符#),遇到数字就将其加入string类型的numStr中,要保证整个数串都被加入,当遇到运算符时,将该string转为数字后压入数字串,这时候我们看看符号栈,如果符号栈为空则压入符号(说明数字栈里只有一个数字);如果非空且栈顶运算符是*和/的话就立刻取出两个操作数做运算,能保证乘除法比加减法先算。这样的话不断处理完了乘除法,最后需要做的只是做整个数字栈的加减法

AC代码如下:

#include <iostream>
#include <stack>
#include <string>
#include <cstdlib>
#include <cctype>
using namespace std;

int main()
{
    string data;
    string numStr = "";
    while (cin >> data)
    {
        data += '#'; //表达式末尾添加结束符#
        stack<double> num; //存放操作数
        stack<char> op;	//存放运算符
        for (int i = 0; data[i]; ++i)
        {
            if(isdigit(data[i])) //取到整个数串
                numStr += data[i]; 
            else
            {
                num.push(atoi(numStr.c_str())); //数字入栈
                numStr = "";
                if (!op.empty()) //只取出乘法或除法运算符
                {
                    char c = op.top();
                    if (c == '*') //处理乘法
                    {
                        op.pop();
                        int b = num.top();num.pop();
                        int a = num.top();num.pop();
                        num.push(a*b);
                    }
                    if (c == '/') //处理除法
                    {
                        op.pop();
                        int b = num.top();num.pop();
                        int a = num.top();num.pop();
                        num.push(a/b);
                    }
                }
                if(data[i] != '#') op.push(data[i]); //当前运算符入栈
            }
        }
        while(!op.empty()) //处理剩余的加减法
        {
            char c = op.top();
            if (c == '+')
            {
                op.pop();
                int b = num.top();num.pop();
                int a = num.top();num.pop();
                num.push(a+b);
            }
            if (c == '-')
            {
                op.pop();
                int b = num.top();num.pop();
                int a = num.top();num.pop();
                num.push(a-b);
            }
        }
        cout << num.top() << endl;
    }
    return 0;
}

内存占用:1524Kb  耗时:10ms

算法复杂度:O(n)

转载于:https://www.cnblogs.com/lecholin/p/6705281.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值