背景:
我们的教材中已经介绍了表达式求值的算法,现在我们将该算法的功能进行扩展,要求可以处理的运算符包括:+、-、*、/、%(整数取余)、^(乘方)、(、)。
要求:
采用算符优先算法,计算的中间结果只保留整数。
输入:
第一行为整数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 |
代码如下:
(参考文章:1. https://blog.csdn.net/xindada559/article/details/104123377 2.https://blog.csdn.net/qq_41317652/article/details/82958188)
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#define MAX 1000000
int num[100];
char sym[100];
int topf = -1;
int tops = -1;
char operation[9] = {'+', '-', '*', '/', '(', ')', '#', '^', '%'};
char check[9][9] = {
{'>', '>', '<', '<', '<', '>', '>', '<', '<'},
{'>', '>', '<', '<', '<', '>', '>', '<', '<'},
{'>', '>', '>', '>', '<', '>', '>', '<', '>'},
{'>', '>', '>', '>', '<', '>', '>', '<', '>'},
{'<', '<', '<', '<', '<', '=', ' ', '<', '<'},
{'>', '>', '>', '>', ' ', '>', '>', '>', '>'},
{'<', '<', '<', '<', '<', ' ', '=', '<', '<'},
{'>', '>', '>', '>', '<', '>', '>', '<', '>'},
{'>', '>', '>', '>', '<', '>', '>', '<', '>'}};
int record(char *q)
{
return (int)(*q - '0');
}
void push_n(int q)
{
num[++topf] = q;
}
int pop_n()
{
return num[topf--];
}
void push_s(char ch)
{
sym[++tops] = ch;
}
char pop_s()
{
return sym[tops--];
}
char compare(char x, char y)
{
int a, b;
for (int i = 0; i < 9; i++)
{
if (operation[i] == x)
{
a = i;
break;
}
}
for (int i = 0; i < 9; i++)
{
if (operation[i] == y)
{
b = i;
break;
}
}
return check[a][b];
}
int operate(int x, int y, char sym)
{
switch (sym)
{
case '+':
return x + y;
case '-':
return x - y;
case '*':
return x * y;
case '/':
if (y)
return x / y;
else
{
printf("Divide 0.\n");
return MAX;
}
case '%':
return (int)fmod(x, y);
case '^':
if (y >= 0)
return (int)pow(x, y);
else
{
printf("error.\n");
return MAX;
}
default:
printf("error.\n");
return MAX;
}
}
int main()
{
int n, flag;
char Formula[100], *p, *Ne, firstnega = '0';
scanf("%d", &n);
while (n--)
{
flag = 2;
memset(Formula, '\0', 100);
scanf("%s", Formula);
strcat(Formula, "#");
p = Formula;
Ne = Formula;
if (*Ne == '-' && *(Ne + 1) == '(')
push_n(record(&firstnega));
if (*Ne == '-' && *(Ne + 1) >= '0' && *(Ne + 1) <= '9')
*Ne = '0';
Ne++;
for (; *Ne != '\0'; Ne++)
{
if ((*(Ne - 1) < '0' || *(Ne - 1) > '9') && (*Ne == '-') && *(Ne - 1) != ')')
*Ne = '0';
}
push_s('#');
k:
while (*p != '#' || sym[tops] != '#')
{
if (*p >= '0' && *p <= '9')
{
if (flag == 0)
{
if (num[topf] <= 0)
push_n(pop_n() * 10 + record(p++) * (-1));
else
push_n(pop_n() * 10 + record(p++));
}
else
push_n(record(p++));
flag = 0;
}
else
{
if (flag == 1)
{
if (*p == '+' || *p == '-' || *p == '*' || *p == '/' || *p == '%' || *p == '^')
{
printf("error.\n");
goto j;
}
}
if (*p == '(')
flag = 1;
else
flag = 2;
if (tops == -1)
{
printf("error.\n");
goto j;
}
else
{
char ch = pop_s(), ans;
ans = compare(ch, *p);
if (ans == ' ')
{
printf("error.\n");
goto j;
}
else if (ans == '<')
{
push_s(ch);
push_s(*p++);
goto k;
}
else if (ans == '=')
{
p++;
goto k;
}
else
{
int integer_x, integer_y;
integer_y = pop_n();
integer_x = pop_n();
int judge = operate(integer_x, integer_y, ch);
if (judge == MAX)
goto j;
else
push_n(judge);
continue;
}
p++;
}
}
}
if (topf == 0 && tops == 0)
printf("%d\n", num[topf]);
else
{
printf("error.\n");
}
j:
memset(Formula, '\0', 100);
topf = -1;
tops = -1;
}
return 0;
}