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