表达式求值

背景:

我们的教材中已经介绍了表达式求值的算法,现在我们将该算法的功能进行扩展,要求可以处理的运算符包括:+、-、*、/、%(整数取余)、^(乘方)、(、)。

要求:

采用算符优先算法,计算的中间结果只保留整数。

输入:

第一行为整数N。表示下面有N个表达式

从第二行起的后面N行为N个由整数构成的表达式

输出:

共N行,每行为相应表达式的计算结果。

如果判断出表达式有错误,则输出:error.

如果在计算过程中出现除数为0的情况,则输出:Divide 0.

特殊情况说明:

在表达式中,如果操作数出现负数(例如-8),则要特别注意。例如:
10加-8表示为:10+-8。
10减-8表示为:10--8。

测试输入期待的输出时间限制内存限制额外进程
测试用例 1以文本方式显示
  1. 4↵
  2. 2^3↵
  3. 2^0↵
  4. 2^3^2↵
  5. 2^(3-1)^(10-8)↵
以文本方式显示
  1. 8↵
  2. 1↵
  3. 512↵
  4. 16↵
1秒64M0
测试用例 2以文本方式显示
  1. 11↵
  2. (2+8↵
  3. 2+8)↵
  4. 8/0↵
  5. 8/(8+5-13)↵
  6. 2^(2-5)↵
  7. 10-(80-30(/3*3+4↵
  8. 10-80-30)/3*3+4↵
  9. (2+8)(3+2)↵
  10. (2)3(8)↵
  11. 30(/3+3)+4↵
  12. 10(20-8)+2↵
以文本方式显示
  1. error.↵
  2. error.↵
  3. Divide 0.↵
  4. Divide 0.↵
  5. error.↵
  6. error.↵
  7. error.↵
  8. error.↵
  9. error.↵
  10. error.↵
  11. error.↵
1秒64M0
测试用例 3以文本方式显示
  1. 2↵
  2. 10(10)↵
  3. 14*10-(10)2↵
以文本方式显示
  1. error.↵
  2. error.↵
1秒64M0
测试用例 5以文本方式显示
  1. 14↵
  2. 18-32↵
  3. 18/4↵
  4. 18%3↵
  5. 10+20*4↵
  6. 10-20/4↵
  7. (18-3)*3↵
  8. 10*(10)↵
  9. (10+2)/(8-10)↵
  10. (2*3)/(5*2)↵
  11. 10-(80-30)/3*3+4↵
  12. (((2+8)*2-(2+4)/2)*2-8)*2↵
  13. (((8+2)*(4/2)))↵
  14. 10/0↵
  15. (10-80*2↵
以文本方式显示
  1. -14↵
  2. 4↵
  3. 0↵
  4. 90↵
  5. 5↵
  6. 45↵
  7. 100↵
  8. -6↵
  9. 0↵
  10. -34↵
  11. 52↵
  12. 20↵
  13. Divide 0.↵
  14. error.↵
1秒64M0

代码如下: 

(参考文章:1. icon-default.png?t=N7T8https://blog.csdn.net/xindada559/article/details/104123377    2.icon-default.png?t=N7T8https://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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值