表达式求值

来源:互联网 发布:noip复赛算法总结 编辑:程序博客网 时间:2024/05/16 11:42

背景:

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

要求:

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

输入:

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

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

输出:

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

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

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

特殊情况说明:

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

测试输入

42^32^02^3^22^(3-1)^(10-8)

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

测试输出

8151216

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 0
原创粉丝点击