表达式求值

背景:

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

要求:

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

输入:

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

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

输出:

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

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

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

特殊情况说明:

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

测试输入

4
2^3
2^0
2^3^2
2^(3-1)^(10-8)

11
(2+8
2+8)
8/0
8/(8+5-13)
2^(2-5)
10-(80-30(/3*3+4
10-80-30)/3*3+4
(2+8)(3+2)
(2)3(8)
30(/3+3)+4
10(20-8)+2

测试输出

8
1
512
16

error.
error.
Divide 0.
Divide 0.
error.
error.
error.
error.
error.
error.
error.

源代码

#include <stdio.h>  
#include <math.h>  
#include <string.h>  
char yunsuanshi[100], *p;     //运算式存储字符串,运算式当前读取位置   
  
struct t                // 建立符号栈   
{   char dat[100];  
    int top;  
}prt;  
  
struct d        //建立数字栈   
{   long int dat[100];  
    int top;  
}prd;  
  
char Prior[9][9]=                                  //优先级列表  
{   {'>','>','<','<','<','<','<','>','>'},  
    {'>','>','<','<','<','<','<','>','>'},  
    {'>','>','>','>','<','<','<','>','>'},  
    {'>','>','>','>','<','<','<','>','>'},  
    {'>','>','>','>','>','<','<','>','>'},  
    {'>','>','>','>','>','<','<','>','>'},  
    {'<','<','<','<','<','<','<','=',' '},  
    {'>','>','>','>','>','>',' ','>','>'},  
    {'<','<','<','<','<','<','<',' ','='}   
};  
  
void pushd(long int a){   //数字入栈  
    prd.dat[prd.top++]=a;    
}  
  
void pusht(char a){          //符号入栈  
    prt.dat[prt.top++]=a;  
}  
  
int popd( ){        //数字出栈   
    return prd.dat[--prd.top];    
}  
  
char popt( ){       //符号出栈  
    return prt.dat[--prt.top];   
}  
  
int numble ( ){         //数字整理   
    long int b=0;  
    do{   
        b = b*10 + *p -'0';  
        p++;  
      }  
    while( *p>='0' &&  *p<='9' ) ;  
        return b;  
}  
  
int operation ( int x, char a, int y) { // 数学运算   
    switch(a){    
        case '+': return x+y;  
        case '-': return x-y;  
        case '*': return x*y;  
        case '/': if ( y )  
                    return x/y;  
                  else{    
                    printf("Divide 0.\n");  
                    return 0;  
                  }  
        case '%': return (int) fmod(x,y);  
        case '^': if (y>=0 )   
                    return (int) pow(x,y);  
                  else         
                    return 0;  
        default:  printf("error. \n");  
                  return 0;  
    }  
}  
  
int signswitch ( char a ){                 //符号转换  
    char signs[]={ '+', '-', '*', '/', '%', '^', '(', ')', '#', '\0' };   
    int k;  
    k = 0;  
    while ( signs[k]!='\0' && signs[k] != a )  
        k++;  
    if ( signs[k] == a )   
        return k;  
    else                  
        return -1;  
}  
  
char refusal ( char a,char b ) {                // 判定优先级  
    return Prior[signswitch(a)][signswitch(b)];    
}  
  
int main( )  
{   int j, k, l;  
    int flag=0;       //flag=0表示前一个符号不是)   
    int n;   
    char b;  
    prt.dat[0]='#';  
    prt.top=1;  
    prd.top=0;  
    scanf("%d",&n);  
    for(int i=1;i<=n;i++){  
    k:;   
    printf ("");  
    scanf("%s", yunsuanshi);     // 接收运算式   
    strcat( yunsuanshi, "#" );   //在运算式结尾加#号   
    p = yunsuanshi;  
    while ( *p!='#' || prt.dat[prt.top-1]!='#' ){     
        if ( *p>='0' && *p<='9')  
            pushd(numble());  
        else {          //如果是符号与栈顶的符号比较并运算   
            if ( flag==1 && *p=='(' ){    
                printf("error.\n");  
                return 1;  
            }  
            else if ( *p==')')    
                    flag=1;  
                 else             
                    flag=0;  
            switch ( refusal(prt.dat[prt.top-1], *p ) ){    // 当前运算符优先级高则运算符入栈   
                case '<':   
                        pusht ( *p++ ); //处理下一个字符                             
                        break;  
                case '=':  
                        popt( );         //脱括号   
                        p++;  
                        break;  
                case '>':   
                        b=popt( );               // 当前运算符优先级低则进行栈顶计算  
                        k=popd();                //第二操作数出栈   
                        l=popd();                //第一操作数出栈  
                        k=operation(l,b,k);      //计算   
                        pushd(k);                //计算结果入栈    
                        break;  
                case ' ':  
                        printf("error.\n");  
                        goto k;  
                        return 1;  
                 }  
        }  
    }  
    if(prd.dat[prd.top-1]!=0)  
        printf("%d\n",prd.dat[prd.top-1]);       // 输出结果   
    }  
    return 0;  
}  
部分案例可能通不过!!!



  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值