表达式求值

背景:

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

要求:

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

输入:

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

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

输出:

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

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

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

特殊情况说明:

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

 测试输入关于“测试输入”的帮助期待的输出关于“期待的输出”的帮助时间限制关于“时间限制”的帮助内存限制关于“内存限制”的帮助额外进程关于“{$a} 个额外进程”的帮助
测试用例 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
#include "stdio.h"    
#include "string.h"    
#include "math.h"    
#define INT 2147483647    
  
int operand[100];    
char Operator[100];    
int f_top = -1, s_top = -1; //symbol figure  
void push_operand(int q){    
    operand[++f_top] = q;    
}    
  
void push_Operator(char ch){    
    Operator[++s_top] = ch;    
}    
  
char operation[9] = {'+','-','*','/','(',')','#','^','%'};    
int checklist[9][9] = {    
    { 1, 1,-1,-1,-1, 1, 1,-1,-1},    
    { 1, 1,-1,-1,-1, 1, 1,-1,-1},    
    { 1, 1, 1, 1,-1, 1, 1,-1, 1},    
    { 1, 1, 1, 1,-1, 1, 1,-1, 1},    
    {-1,-1,-1,-1,-1, 0,-2,-1,-1},    
    { 1, 1, 1, 1,-2, 1, 1, 1, 1},    
    {-1,-1,-1,-1,-1,-2, 0,-1,-1},    
    { 1, 1, 1, 1,-1, 1, 1,-1, 1},    
    { 1, 1, 1, 1,-1, 1, 1,-1, 1}    
};    
  
int digitise(char *q){    
    return (int)(*q - '0');    
}    
    
  
int operate(int x, int y, char Operator){    
    switch(Operator){    
        case '+': return x+y;    
        case '-': return x-y;    
        case '*': return x*y;    
        case '/': if(y) return x/y;    
                  else{    
                      printf("Divide 0.\n");    
                      return INT;    
                  }    
        case '%': return x%y;    
        case '^': if(y>=0) return pow(x,y);    
                    else{    
                        printf("error.\n");    
                        return INT;    
                    }    
        default: printf("error.\n");    
                 return INT;    
   }    
}    
  
    
int compare(char x, char y){    
    int a,b;    
    for(int i = 0; i <= 8; i++){    
        if(operation[i] == x){    
            a = i;    
            break;    
        }    
    }    
    for(int i = 0; i <= 8; i++){    
        if(operation[i] == y){    
            b = i;    
            break;    
        }    
    }    
    return checklist[a][b];    
}    
  
  
int main(){    
    int n, chtype = 0,over=0;   //0数字,1(,2其他   
    char expression[100], *p,*nega;    
    scanf("%d",&n);    
    while(n--){    
          
        chtype = 2;   
        memset(expression,'\0',100);   
        scanf("%s",expression);    
        strcat(expression, "#"); //加入一个结束符   
        p = expression;  
        nega = expression;  
        if(*nega=='-'&&*(nega+1)>='0'&&*(nega+1)<='9')  
        {  
            *nega='0';  
        }  
          
        nega++;  
        for(;*nega!='\0';nega++)  //消除数字前面的负号   
        {  
            if((*(nega-1)<'0'||*(nega-1)>'9')&&(*nega=='-'))   
            {  
                *nega='0';  
            }                     
         }  
          
          
            
         /*while(*p!='\0') 
         { 
             printf("%c\n",*p); 
             p++; 
         } 
         p=expression;*/  
           
        push_Operator('#');   //加入一个起始符   
  
        while(*p != '#' || Operator[s_top] != '#'){    
            if(*p >='0' && *p <= '9'){              
                if(chtype == 0){    
                    if(operand[f_top]<=0) push_operand(operand[f_top--]*10+digitise(p++)*(-1));  
                    else push_operand(operand[f_top--]*10+digitise(p++));    
                    chtype = 0;    
                }    
                else    
                    push_operand(digitise(p++));    
                    chtype = 0;    
            }    
            else{    
                if(chtype == 1){    
                    if(*p == '+' || *p == '-' || *p == '*' || *p == '/' || *p == '%' ||*p == '^'){    
                        printf("error.\n");    
                        over=1; break;    
                    }    
                }    
                  
                  
                if(*p == '(') chtype = 1;             
                else chtype = 2;   
          
  
                if(s_top == -1){    
                    printf("error.\n");    
                    over=1; break;    
                }    
  
                else{  
                    char ch=Operator[s_top--];  
                    int priority;  //priority为优先级关系   
                    priority = compare(ch, *p);    
                    if(priority == -2){               
                        printf("error.\n");    
                        over=1; break;    
                    }    
                    else if(priority == -1){ //'<'    
                        push_Operator(ch);    
                        push_Operator(*p++);    
                        continue;    
                    }    
                    else if(priority == 0){   //"()" "##"  
                        p++;    
                        continue;    
                    }    
                    else{  //calculate   
                        int num1, num2;    
                        num2 = operand[f_top--];    
                        num1 = operand[f_top--];    
                        int judge = operate(num1, num2, ch);    
                        if(judge == INT)    
                        {  
                             over=1; break;  
                        }    
                        else   
                        {  
                            push_operand(judge);    
                        }                              
                        continue;    
                    }    
                    p++;    
                }                 
           }    
        }    
        if(!over)  
        {  
            if(f_top == 0 && s_top == 0) printf("%d\n",operand[f_top]);    
            else    printf("error.\n");  
        }  
  
        memset(expression,'\0',100);    
        f_top = -1;    
        s_top = -1;  
        over=0;   
                    
    }    
    return 0;    
}  

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值