表达式求值 数据结构 C/C++ 栈的应用

用书上的代码拼凑的,还是很有成就感的哈

支持的运算符号有"+","-","*","/","(",")","#"。

支持20位以内无符号整数,当然可以很容易的改成有符号或者是实型数

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define OPSETSIZE 7
//函数结果状态代码
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
//Status是函数的类型,其值是函数结果状态代码 
typedef int Status;
#define STACK_INIT_SIZE 1000 //存储空间初始分配量
typedef struct{
        char *base;
        char *top;
        int stacksize;
}StackChar;

typedef struct{
        float *base;
        float *top;
        int stacksize;
}StackFloat;

unsigned char Prior[7][7] = {     // 表3.1  算符间的优先关系
  	  '>','>','<','<','<','>','>',
	  '>','>','<','<','<','>','>',
	  '>','>','>','>','<','>','>',
	  '>','>','>','>','<','>','>',	
	  '<','<','<','<','<','=',' ',
	  '>','>','>','>',' ','>','>',
	  '<','<','<','<','<',' ','='
};		
float Operate(float a, unsigned char theta, float b);
char OPSET[OPSETSIZE]={'+' , '-' , '*' , '/' ,'(' , ')' , '#'};
Status In(char Test,char* TestOp);
char precede(char Aop, char Bop);
int atof(char* snum){
    int l=strlen(snum),i=1,sum=snum[l-1]-'0';
    l--;
    while(l--){
         i*=10;
         sum+=(snum[l]-'0')*i;
    }
    return sum;
}
          
    
void InitStackChar(StackChar &S){
     //构造一个空栈S
     S.base=(char*)malloc(STACK_INIT_SIZE * sizeof(char));
     if(!S.base) exit(OVERFLOW);
     S.top=S.base;
     S.stacksize=STACK_INIT_SIZE;
}
void InitStackFloat(StackFloat &S){
     //构造一个空栈S
     S.base=(float*)malloc(STACK_INIT_SIZE * sizeof(float));
     if(!S.base) exit(OVERFLOW);
     S.top=S.base;
     S.stacksize=STACK_INIT_SIZE;
}
char GetTopChar(StackChar S){
     //返回S的栈顶元素
     return *(S.top-1);
}
float GetTopFloat(StackFloat S){
     //返回S的栈顶元素
     return *(S.top-1);
}
void PushChar(StackChar &S,char e){
     *S.top++=e;
}
void PushFloat(StackFloat &S,float e){
     *S.top++=e;
}
void PopChar(StackChar &S,char &e){
     e=*--S.top;
}   
void PopFloat(StackFloat &S,float &e){
     e=*--S.top;
}   
float EvaluateExpression(char* MyExpression) {  // 算法3.4
   // 算术表达式求值的算符优先算法。
   // 设OPTR和OPND分别为运算符栈和运算数栈,OP为运算符集合。
   StackChar  OPTR;    // 运算符栈,字符元素
   StackFloat OPND;    // 运算数栈,实数元素
   char TempData[20];//支持整数位数 
   float Data,a,b;
   char theta,*c,x,Dr[2];
   
   InitStackChar (OPTR);
   PushChar (OPTR, '#');
   InitStackFloat (OPND);
   c = MyExpression;
   strcpy(TempData,"/0");
   while (*c!= '#' || GetTopChar(OPTR)!= '#') {
      if (!In(*c, OPSET)) {
      	 Dr[0]=*c;
      	 Dr[1]='/0';
         strcat(TempData,Dr);
         c++;
         if(In(*c,OPSET)) {
            Data=(float)atof(TempData);
            PushFloat(OPND, Data);
            strcpy(TempData,"/0");
         }
      } else {   // 不是运算符则进栈
         switch (precede(GetTopChar(OPTR), *c)) { 
            case '<':   // 栈顶元素优先权低
                 PushChar(OPTR, *c);  
                 c++;
                 break;
            case '=':   // 脱括号并接收下一字符
                 PopChar(OPTR, x);   
                 c++;
                 break;
            case '>':   // 退栈并将运算结果入栈
                 PopChar(OPTR, theta);
                 PopFloat(OPND, b);  
                 PopFloat(OPND, a);                      
                 PushFloat(OPND, Operate(a, theta, b)); 
                 break;
         } // switch
      }
   } // while
   return GetTopFloat(OPND);
} // EvaluateExpression

float Operate(float a,unsigned char theta, float b) {
   switch(theta) {
      case '+': return a+b;
      case '-': return a-b;
      case '*': return a*b;
      case '/': return a/b;
      default : return 0;
   } 
}	

Status In(char Test,char* TestOp) {
   bool Find=false;
   for (int i=0; i< OPSETSIZE; i++) {
      if (Test == TestOp[i]) Find= true;
   }
   return Find;
}

int ReturnOpOrd(char op,char* TestOp) {
   int i;
   for(i=0; i< OPSETSIZE; i++) {
      if (op == TestOp[i]) return i;
   }
   return 0;
}

char precede(char Aop, char Bop) {
   return Prior[ReturnOpOrd(Aop,OPSET)][ReturnOpOrd(Bop,OPSET)];
}

int main()
{
    char s[1001];
    long long result;
    int len;
    printf("输入一行表达式,以#结束:/n");
    while(gets(s)){
          result=(long long)EvaluateExpression(s);
          printf("结果是:%d/n",result);
          printf("继续输入吧:/n");
    }
}


因为有"&"引用符号,所以要当作C++编译

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值