成绩 | 15 | 开启时间 | 2017年10月18日 星期三 14:00 |
折扣 | 0.8 | 折扣时间 | 2017年11月8日 星期三 23:55 |
允许迟交 | 否 | 关闭时间 | 2018年01月8日 星期一 23:55 |
背景:
我们的教材中已经介绍了表达式求值的算法,现在我们将该算法的功能进行扩展,要求可以处理的运算符包括:+、-、*、/、%(整数取余)、^(乘方)、(、)。
要求:
采用算符优先算法,计算的中间结果只保留整数。
输入:
第一行为整数N。表示下面有N个表达式
从第二行起的后面N行为N个由整数构成的表达式
输出:
共N行,每行为相应表达式的计算结果。
如果判断出表达式有错误,则输出:error.
如果在计算过程中出现除数为0的情况,则输出:Divide 0.
特殊情况说明:
在表达式中,如果操作数出现负数(例如-8),则要特别注意。例如:
10加-8表示为:10+-8。
10减-8表示为:10--8。
测试输入 | 期待的输出 | 时间限制 | 内存限制 | 额外进程 | |
---|---|---|---|---|---|
测试用例 1 | 以文本方式显示
| 以文本方式显示
| 1秒 | 64M | 0 |
测试用例 2 | 以文本方式显示
| 以文本方式显示
| 1秒 | 64M | 0 |
测试用例 3 | 以文本方式显示
| 以文本方式显示
| 1秒 | 64M | 0 |
测试用例 5 | 以文本方式显示
| 以文本方式显示
| 1秒 | 64M | 0 |
#include<cstdio>
#include<string>
#include<map>
#include<stack>
#include<math.h>
#include<iostream>
using namespace std;
map<string, int> Varible;
stack<char> Op;
stack<int> Opnum;
string Instruction;
string tmp;
int flag;
int GetproiIncoming(char c)
{
switch (c)
{
case('+') : return 3;
case('-') : return 3;
case('*') : return 5;
case('/') : return 5;
case('%') : return 5;
case('(') : return 10;
case('^') : return 8;
}
}
int GetproInstack(char c)
{
switch (c)
{
case('+') : return 4;
case('-') : return 4;
case('*') : return 6;
case('/') : return 6;
case('%') : return 6;
case('(') : return 1;
case('^') : return 7;
}
}
int Comput(char c, int a, int b)
{
switch (c)
{
case('+') : return a + b;
case('-') : return a - b;
case('*') : return a*b;
case('/') : return a / b;
case('%') : return a%b;
case('^') : return (int)pow(double(a), double(b));
}
}
int Getvar(string tmp)
{
int num = 0; flag = 0;
int numleft = 0; int numright = 0;
for (int i = 0; tmp[i]; i++)
{
if (tmp[i] >= '0'&&tmp[i] <= '9')
{
if (i>0&&tmp[i - 1] == ')')
{
flag = 1;
return -1;
}
num = num * 10 + tmp[i] - '0';
}
else if (!(tmp[i] >= '0'&&tmp[i] <= '9'))
{
if (i > 0 && tmp[i - 1] == '(' && (tmp[i] == '%' || tmp[i] == '*' || tmp[i] == '/' || tmp[i] == '^'))
{
flag = 1; return -1;
}
if (i>0&&(tmp[i - 1] >= '0'&&tmp[i - 1] <= '9'))
{
Opnum.push(num); num = 0;
}
else if (i == 0 && (tmp[i] == '+' || tmp[i] == '-') && (tmp[i+1] >= '0'&&tmp[i+1] <= '9'))
{
i++; int k = i;
while (tmp[k] && (tmp[k] >= '0'&&tmp[k] <= '9'))
{
num = num * 10 + tmp[k] - '0'; k++;
}
if (tmp[i - 1] == '-') num *= -1; i = k - 1; continue;
}
else if (i == 0 && (tmp[i] == '%' || tmp[i] == '*' || tmp[i] == '/' || tmp[i] == '^'))
{
flag = 1;
return -1;
}
else if (i>0 && !(tmp[i - 1] >= '0'&&tmp[i - 1] <= '9') && (tmp[i] == '+' || tmp[i] == '-') && (tmp[i + 1] >= '0'&&tmp[i + 1] <= '9'))
{
i++; int k = i;
while (tmp[k] && (tmp[k] >= '0'&&tmp[k] <= '9'))
{
num = num * 10 + tmp[k] - '0'; k++;
}
if (tmp[i - 1] == '-') num *= -1; i = k - 1; continue;
}
if (Op.empty() || tmp[i] == '(')
{
if (tmp[i] == '(')
{
if (i > 0 && (tmp[i - 1] >= '0'&&tmp[i - 1] <= '9'||tmp[i-1]==')'))
{
flag = 1;
return -1;
}
}
Op.push(tmp[i]);
if (tmp[i] == '(') numleft++;
continue;
}
else if (tmp[i] == ')')
{
numright++;
if (numright > numleft)
{
flag = 1;
return -1;
}
char op;
while (!Op.empty() && (op = Op.top()) != '(')
{
int b = Opnum.top(); Opnum.pop();
int a = Opnum.top(); Opnum.pop();
if (b == 0 && op == '/')
{
flag = 2; return -1;
}
else if (b < 0 && op == '^')
{
flag = 1; return -1;
}
else { Opnum.push(Comput(op, a, b)); }
Op.pop();
}
Op.pop();
}
else
{
int Incoming = GetproiIncoming(tmp[i]);
int Instack;
char op;
while (!Op.empty() && (Instack = GetproInstack(Op.top())) > Incoming)
{
op = Op.top();
int b = Opnum.top(); Opnum.pop();
int a = Opnum.top(); Opnum.pop();
if (b == 0 && op == '/')
{
flag = 2; return -1;
}
else if (b < 0 && op == '^')
{
flag = 1; return -1;
}
else { Opnum.push(Comput(op, a, b)); }
Op.pop();
}
Op.push(tmp[i]);
}
}
}
if (tmp[tmp.length() - 1] >= '0'&&tmp[tmp.length() - 1] <= '9')
Opnum.push(num);
if (!Op.empty() || !Opnum.empty())
{
while (!Op.empty())
{
char op = Op.top();
if (op == '(')
{
flag = 1;
return -1;
}
int b = Opnum.top(); Opnum.pop();
int a = Opnum.top(); Opnum.pop();
if (b == 0 && op == '/')
{
flag = 2; return -1;
}
else if (b < 0 && op == '^')
{
flag = 1; return -1;
}
else { Opnum.push(Comput(op, a, b)); }
Op.pop();
}
return Opnum.top();
}
else return num;
}
int main()
{
//freopen("1.txt", "r", stdin);
int T;
scanf("%d%*c", &T);
while (T--)
{
while (!Op.empty())
Op.pop();
while (!Opnum.empty())
Opnum.pop();
getline(cin, Instruction);
int ans=Getvar(Instruction);
if (flag==1)
printf("error.\n");
else if (flag == 2)
{
printf("Divide 0.\n");
}
else
{
printf("%d\n", ans);
}
}
return 0;
}