cdoj 2015数据结构专题:N - 秋实大哥搞算数

秋实大哥大学物理挂科了,于是在下学期的前两周的某一天要悲剧的补考。为了不给学校的挖掘机大楼做贡献,秋实大哥决定在假期里努力复习。当然,良好的计算能力也是非常必要的,毕竟是涉及计算自己做多少分的题能够通过考试的问题。现在他给自己出了一大堆长长的只有涉及整形四则运算式子,然后埋头计算结果。为了检验自己的计算能力,他请你来帮忙。

Input

第一行一个整数T,表示式子的总数。

接下来每一行有一个长度不超过10^6的表达式,只包含正整数和四则运算符号('+', '-', '*', '/')。

保证输入合法。

Output

对于每一个表达式,输出相应的结果,占一行。

保证运算及结果在long long范围以内。

Sample input and output

Sample Input Sample Output
2
12+5/4-1
4*5/3
12
6


用栈实现。

建立一个char类型的栈和一个long long 类型的栈,前者存运算符,后者存数字。将一个式子分解为第一个数和一组运算符加数,所以每一个式子先读入一个数并将其入栈,之后每次读入一个运算符和一个数,并将其入栈,直到式子结束。因为要先乘除后加减,所以在读入一组运算符加数时,如果运算符为乘除,就将有乘除的部分计算,将计算结果入栈,再继续读入。

此后的栈内只有加减法,但是是逆序排列,不能从后向前遍历计算,因为当前面是减法时,后面的减法应该变成加法,而逆序计算不能实现,会使最后结果错误。将两个栈的元素依次导入另两个栈中,保证从栈顶取元素时是按式子顺序从前往后计算而得,依次取出栈顶元素计算得到结果。

需要注意判断式子结束,一是所有输入结束,scanf()等于-1,另一个是读入的字符不为运算符,为间隔符。后者因不知道间隔符具体是什么,判断时应判断是否为四个运算符,而不是判断是否为\n


#include <iostream>
#include <stack>
#include <cstdio>

using namespace std;

stack <char> s,s1;
stack <long long> num,num1;

void div()
{
    long long x, a, b;
    a = num.top();
    num.pop();
    b = num.top();
    num.pop();
    x = b / a;
    num.push(x);
    s.pop();
}

void mul()
{
    long long x, a, b;
    a = num.top();
    num.pop();
    b = num.top();
    num.pop();
    x = b * a;
    num.push(x);
    s.pop();
}

void add()
{
    long long x, a, b;
    a = num1.top();
    num1.pop();
    b = num1.top();
    num1.pop();
    x = a + b;
    num1.push(x);
    s1.pop();
}

void red()
{
    long long x, a, b;
    a = num1.top();
    num1.pop();
    b = num1.top();
    num1.pop();
    x = a - b;
    num1.push(x);
    s1.pop();
}

void cha()
{
    while(!s.empty()){
        s1.push(s.top());
        s.pop();
    }
    while(!num.empty()){
        num1.push(num.top());
        num.pop();
    }
}
int main()
{
    int n;
    long long x;
    char c;
    scanf("%d",&n);
    while(n--){
        while(!s.empty())   s.pop();
        while(!num.empty()) num.pop();
        scanf("%lld",&x);
        num.push(x);
        while(scanf("%c",&c) != -1 && (c == '*' || c == '/' || c =='+' ||c == '-')){
            scanf("%lld",&x);
            s.push(c);
            num.push(x);
            if(c == '/')
                div();
            else if(c == '*')
                mul();
        }
        cha();
        while(!s1.empty()){
            if(s1.top() == '+')
                add();
            else
                red();
        }
        printf("%lld\n",num1.top());
    }
    return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值