这篇博客介绍的表达式求值是用C语言实现的,只使用了c++里面的引用。
数据结构课本上的一个例题,但是看起来很简单,实现却遇到了很多问题。
这个题需要构建两个栈,一个用来存储运算符OPTR, 一个用来存储数字OPND。
但是,数字和运算符都定义成字符型栈吗?
出现了问题,当运算结果或中间结果为负时,没有办法存储。而且只能运算0~9之间的数字结果也只能是0~9之间。
那就运算符栈为字符栈, 数字栈为数值型栈,在存储时将表达式中的字符转化成数值进行存储。
但是,如果我们不用c++里面的stack进行栈的定义,而是用C语言进行实现,这种方法实现起来好像也没有这么简单,代码很多。两种栈的元素类型不一样,操作很繁琐。
怎么办呢, 我想可以用char类型的ASCII码数值来表示数值,两个栈都定义为字符栈。
数值进行存储时,将读入的字符型变量值减去0的ASCII码值 c - '0' ,然后压栈。
但这样做也有缺陷,应为C语言中char类型只有8位, 那这种方法实现的表达式求值,其结果和中间值的取值范围[ -128, 127] 。
我们主要是学习栈的实现和应用,其实对于这个题来说已经足够了。
下面附上代码的实现:
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 5 #define ElemType char 6 #define STACKINCEMENT 10 7 #define STACK_INIT_SIZE 50 8 9 #define Status int 10 #define OK 1 11 #define ERROR 0 12 #define OVERFLOW -2 13 14 typedef struct{ 15 ElemType *base; 16 ElemType *top; 17 int stacksize; 18 }SqStack; 19 20 Status InitStack(SqStack &S){ 21 S.top = S.base = (ElemType *)malloc(sizeof(ElemType) * STACK_INIT_SIZE); 22 if(!S.top) 23 exit(OVERFLOW); 24 S.stacksize = STACK_INIT_SIZE; 25 return OK; 26 }//InitStack 27 28 Status Push(SqStack &S, ElemType e){ 29 if(S.top - S.base == S.stacksize){ 30 S.base = (ElemType *)realloc(S.base, sizeof(ElemType) * 31 (S.stacksize + STACKINCEMENT)); 32 if(!S.base) exit(OVERFLOW); 33 S.top = S.base + S.stacksize; 34 S.stacksize += STACKINCEMENT; 35 } 36 *S.top++ = e; 37 return OK; 38 }//Push 39 40 Status Pop(SqStack &S, ElemType &e){ 41 if(S.base == S.top) return ERROR; 42 43 e = *--S.top; 44 return OK; 45 }//Pop 46 47 ElemType GetTop(SqStack S){ 48 if(S.base == S.top) return ERROR; 49 return *--S.top; 50 }//GetTop 51 52 Status In(ElemType c){ 53 if(c=='+'||c=='-'||c=='*'||c=='/'||c=='#'||c=='('||c==')'||c=='['||c==']') 54 return 1; 55 else 56 return 0; 57 }//In 58 59 char Precede(ElemType a, ElemType b){ 60 if(a=='+'||a=='-'){ 61 if(b=='+'||b=='-'||b=='>'||b=='#'||b==')'||b==']') 62 return '>'; 63 else return '<'; 64 } 65 if(a=='*'||a=='/'){ 66 if(b=='('||b=='[') 67 return '<'; 68 else return '>'; 69 } 70 if(a=='('){ 71 if(b==')') 72 return '='; 73 else return '<'; 74 } 75 if(a=='['){ 76 if(b==']') 77 return '='; 78 else return '<'; 79 } 80 if(a=='#'){ 81 if(b=='#') 82 return '='; 83 else return '<'; 84 } 85 }//Precede 86 87 ElemType Operate(ElemType a, ElemType x, ElemType b){ 88 switch (x){ 89 case '+': 90 return a + b; 91 case '-': 92 return a - b; 93 case '*': 94 return a * b; 95 case '/': 96 return a / b; 97 } 98 }//Operator 99 100 ElemType EvaluateExpression(){ 101 SqStack OPTR, OPND; 102 InitStack(OPTR); //操作符 103 Push(OPTR, '#'); 104 InitStack(OPND); //操作数 105 106 char x, c[100]; 107 gets(c); 108 int i=0; 109 while(c[i] != '#' || GetTop(OPTR)!='#'){ 110 if(!In(c[i])) { 111 if(i>0 && (c[i-1]>'0'&& c[i-1]<='9')){ 112 Pop(OPND, x); 113 Push(OPND, 10*x + c[i] - '0'); 114 } 115 else Push(OPND, c[i] - '0'); 116 i++; 117 } 118 else 119 switch(Precede(GetTop(OPTR), c[i])){ 120 case '<': 121 Push(OPTR, c[i]); 122 i++; 123 break; 124 case '=': 125 Pop(OPTR, x); 126 i++; 127 break; 128 case '>': 129 Pop(OPTR, x); 130 ElemType a, b; 131 Pop(OPND, b); Pop(OPND, a); 132 Push(OPND, Operate(a, x, b)); 133 break; 134 } 135 } 136 return GetTop(OPND); 137 }//EvaluateExpression 138 139 int main(){ 140 SqStack S; 141 InitStack(S); 142 printf("%d",EvaluateExpression()); 143 144 return 0; 145 }