1. 程式人生 > >表示式求值--資料結構課本演算法實現

表示式求值--資料結構課本演算法實現

這篇部落格介紹的表示式求值是用C語言實現的,只使用了c++裡面的引用。

資料結構課本上的一個例題,但是看起來很簡單,實現卻遇到了很多問題。

這個題需要構建兩個棧,一個用來儲存運算子OPTR, 一個用來儲存數字OPND。

但是,數字和運算子都定義成字元型棧嗎?

出現了問題,當運算結果或中間結果為負時,沒有辦法儲存。而且只能運算0~9之間的數字結果也只能是0~9之間。

那就運算子棧為字元棧, 數字棧為數值型棧,在儲存時將表示式中的字元轉化成數值進行儲存。

但是,如果我們不用c++裡面的stack進行棧的定義,而是用C語言進行實現,這種方法實現起來好像也沒有這麼簡單,程式碼很多。兩種棧的元素型別不一樣,操作很繁瑣。

怎麼辦呢, 我想可以用char型別的ASCII碼數值來表示數值,兩個棧都定義為字元棧。

數值進行儲存時,將讀入的字元型變數值減去0的ASCII碼值  c - '0' ,然後壓棧。

但這樣做也有缺陷,應為C語言中char型別只有8位, 那這種方法實現的表示式求值,其結果和中間值的取值範圍[ -127, 128] 。

 我們主要是學習棧的實現和應用,其實對於這個題來說已經足夠了。

 

下面附上程式碼的實現:

  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 }