您的位置:首页 > 理论基础 > 数据结构算法

NYOJ-35-表达式求值(C语言数据结构)

2013-07-31 09:48 465 查看
/*http://acm.nyist.net/JudgeOnline/problem.php?pid=35

表达式求值

时间限制:3000 ms  |  内存限制:65535 KB

难度:4

描述

ACM队的mdd想做一个计算器,但是,他要做的不仅仅是一计算一个A+B的计算器,他想实现随便输入一个表达式都能求出它的值的计算器,现在请你帮助他来实现这个计算器吧。

比如输入:“1+2/4=”,程序就输出1.50(结果保留两位小数)

输入

第一行输入一个整数n,共有n组测试数据(n<10)。

每组测试数据只有一行,是一个长度不超过1000的字符串,表示这个运算式,每个运算式都是以“=”结束。这个表达式里只包含+-*/

/*与小括号这几种符号。其中小括号可以嵌套使用。数据保证输入的操作数中不会出现负数。

数据保证除数不会为0

输出

每组都输出该组运算式的运算结果,输出结果保留两位小数。

样例输入

2

1.000+2/4=

((1+2)*5+1)/4=

样例输出

1.50

4.00

来源

数据结构课本例题改进

上传者

张云聪

*/

#include<stdio.h>//

#include<stdlib.h>

#include<string.h>

#include<stack>

using namespace std;

char pk(char a,char b){//比较运算符的优先级

     if(a=='*'||a=='/'){

          if(b=='+'||b=='-'||b=='*'||b=='/'||b==')'||b=='=')

                    return '>';

           else     return '<';

     }

       

      else if(a=='+'||a=='-'){

          if(b=='+'||b=='-'||b==')'||b=='=')

                  return '>';    

          else    return '<';

          

      }

      else if(a=='('||a=='#'){

           if((a=='('&&b==')')||(a=='='&&b=='=') )

                  return '=';

           else   return '<';

      }

}       

   double  oper(double x,char c,double y)

   {

          

           if(c=='+')

                return x+y;

            else if(c=='-')

                return x-y;

            else if(c=='*')

                return x*y;

            else 

                return x/y;  

            

            

    

     }

int main (){

 

 int N,i,j;

 scanf("%d",&N);

 while(N--){

      char str[2000];

      char ok[200];

      stack<char>sc;      //char型栈

      sc.push('#');          

      stack<double>sd;   //double型栈

      scanf("%s",str);

      int end=0,loop=0;

      int len=strlen(str);

      for(i=0;i<len;){

              if(str[i]=='='&&sc.top()=='#'){//若最后一位字符为‘=’,double型栈顶为‘#’,即为比较计算完毕

                  break;

              }

         if(str[i]>='0'&&str[i]<='9'||str[i]=='.'){//转化字符串为实数_01

          ok[end++]=str[i];

       loop=1; 

    i++;

    continue;                    

         }

           if(loop){              ////转化字符串为实数_02,其中的标记,很重要,记录一个浮点数的过程的方法

              ok[end]='\0'; 

      double t=atof(ok);      //字符‘123.08900’转换为123.08900

      end=0;

      loop=0;

      sd.push(t);

                                                   

           }

      switch(pk(sc.top(),str[i])){//匹配运算字符的优先级,并进行出栈,入栈操作

      case'<':sc.push(str[i]);i++;break;

            case'=':sc.pop();i++;break;

         case'>':

             double x,y;

       y=sd.top();sd.pop();

       x=sd.top();sd.pop();

                            char c;

                            c=sc.top();sc.pop();

                            sd.push( oper(x,c,y) );

                            break;                                          

                                                           

           }   

         

       }

       printf("%.2f\n",sd.top());

   

 }

 

return 0; 

}

//完全自己写的,手动创建栈(char 类型栈,double类型栈),手写其(Pop(),Push(),GetTop(),)方法(C语言版数据结构-表达式求值-实现);

#include<stdio.h>

#include<string.h>

#include<stdlib.h>//atof();字符转换为浮点型数据:‘123.09008’——>123.09008

#include<malloc.h>

#define STACK_SIZE 2000

struct Stack{//定义在一个结构体中

  char    *base1;

  char    *top1;

  int     scsize;

  double  *base2;

  double  *top2;

  int     sdsize;

};

  int Stack1(Stack &sc){

      sc.base1=(char *)malloc(STACK_SIZE*sizeof(char));//初始化char类型栈

      sc.top1=sc.base1;

       sc.scsize=STACK_SIZE;

   }

   void Stack2(Stack &sd){

      sd.base2=(double *)malloc(STACK_SIZE*sizeof(double));//初始化double类型栈

      sd.top2=sd.base2;

       sd.sdsize=STACK_SIZE;

   }

   char GetTop1(Stack sc){

     char e1;

     e1=*(sc.top1-1);

  return e1;

          

   }

    double GetTop2(Stack sd){

     double e2;

     e2=*(sd.top2-1);

  return  e2;

          

   }

   void Push1(Stack &sc,char e1){

     

     *sc.top1++=e1;

   }

   void Push2(Stack &sd,double e2){

     

     *sd.top2++=e2;

   }

   void Pop1(Stack &sc){

     //char &e1;

    // e1=*(--sc.top1);

       --sc.top1;

   }

    void Pop2(Stack &sd){

     

     --sd.top2;

   }

  

  

   char pk(char c1,char c2)//运算符大小等级比较 ,(栈顶,下个字符,

  {

 if(c1=='+'||c1=='-')

 {

  if(c2=='+'||c2=='-'||c2==')'||c2=='=')

   return '>';

  else

   return '<';

 }

 else if(c1=='*'||c1=='/')

 {

  if(c2=='+'||c2=='-'||c2=='*'||c2=='/'||c2==')'||c2=='=')

   return '>';

  else

   return '<';

 }

 else if(c1=='('||c1=='#')

 {

  if((c1=='('&&c2==')')||(c1=='#'&&c2=='='))

   return '=';

  else

   return '<';

 }

}

double oper(double x,char c,double y)//运算

{

 if(c=='+')      return x+y;

 else if(c=='-') return x-y;

 else if(c=='*') return x*y;

 else            return x/y;

}

int main()

{ int a,i,j,n;

 scanf("%d",&n);

 while(n--)

 {

  char str[2000];

  char ok[200];

    // char sc[2000];

       //double sd[2000];

  int end=0,loop=0;

  Stack sc,sd;    //声明

  Stack1(sc);

  Push1(sc,'#');    //初始化 

  Stack2(sd);

  scanf("%s",str);

  int len=strlen(str);

  for(i=0;i<len;){

    if(str[i]=='='&&GetTop1(sc)=='#')

                break;

          if(str[i]>='0'&&str[i]<='9'||str[i]=='.')

           {  ok[end++]=str[i++];

         loop=1;

      continue; 

          

           }

           if(loop){

        ok[end]='\0';

         double t=atof(ok);

         Push2(sd,t);

               loop=0;

               end=0;

           }

           switch(pk(GetTop1(sc),str[i])){

           case'<':

             Push1(sc,str[i++]);

       break;

              

              case'=':

          Pop1(sc);i++;

       break;

     case'>':

            double x,y;

      y=GetTop2(sd);Pop2(sd);

      x=GetTop2(sd);Pop2(sd);

      char c;

      c=GetTop1(sc);Pop1(sc);

      Push2(sd,oper(x,c,y)); 

      break; 

           }

         

     

   } 

    printf("%.2f\n",GetTop2(sd));   

}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: