逆波兰表达式(也称为后缀表达式) C 语言简单实现
本示例旨在展示逆波兰表达式原理,作简单的混合运算,不作容错处理也不保证结果。若混合运算字符串中有{ [ %] } 等,自行调试解决
列如计算: -20.5 + ( 100 - ( 3 + 2 ) * 8 ) / ( 8 - 5 ) - 10
后缀表达式为:-20.5 100 3 2 + 8 * - 8 5 - / + 10 -
C 语言代码如下:
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 #define CNT 1000 6 7 struct node{ 8 float num; //数字 9 char op; //操作符 10 }; 11 12 struct node datas[CNT]; //后缀表达式 13 int data_top = -1; //栈顶索引 14 15 char ops[CNT]; //操作符 16 int op_top = -1; //栈顶索引 17 18 char nums[100]; //数字字符串 19 int num_top = -1; //栈顶索引 20 int minus_tag = 1; //负数标记 21 //数字入栈 22 void push_num(){ 23 if(num_top > -1){ 24 datas[++data_top].num = atof(nums) * minus_tag; 25 datas[data_top].op = 0; 26 num_top = -1; 27 minus_tag = 1; 28 memset(nums, 0, sizeof(nums)); 29 } 30 } 31 //中缀转后缀 32 void mtoe(const char* str){ 33 char *tmp; 34 tmp = (char*)str; 35 int last_tag = 1; //上一个字符是否是运算符,默认是,用于处理负数 36 while(*tmp != '\0'){ 37 char ch = *tmp; 38 ++tmp; 39 if(ch == ' ') continue; 40 41 if(ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '('){ 42 push_num(); 43 if( (ch == '-') && last_tag ){ 44 minus_tag = -1;//负数标记 45 last_tag = 0; 46 continue; 47 } 48 last_tag = 1; 49 while(op_top > -1){ 50 if(ch == '(') break; 51 char op = ops[op_top]; 52 if(op == '(') break; 53 if(ch == '+' || ch == '-'){ 54 datas[++data_top].op = op; 55 --op_top; 56 }else{ 57 if(op == '+' || op == '-') break; 58 else{ 59 datas[++data_top].op = op; 60 --op_top; 61 } 62 } 63 } 64 ops[++op_top] = ch; 65 }else if(ch == ')'){ 66 push_num(); 67 last_tag = 0; 68 while(ops[op_top] != '('){ 69 datas[++data_top].op = ops[op_top]; 70 --op_top; 71 } 72 --op_top; 73 }else{ 74 last_tag = 0; 75 nums[++num_top] = ch; 76 } 77 }// end of while *tmp 78 push_num();//最后的数据入栈 79 while(op_top > -1){//最后的操作符入栈 80 datas[++data_top].op = ops[op_top]; 81 --op_top; 82 } 83 84 } 85 //计算值 86 float calculating(){ 87 if(data_top < 0) return 0; 88 float stack[CNT] = {0}; 89 int top = -1; 90 int i = 0; 91 while(i <= data_top){ 92 char op = datas[i].op; 93 if(op == 0){ 94 stack[++top] = datas[i].num; 95 }else{ 96 float a = stack[top -1]; 97 float b = stack[top]; 98 --top; 99 float c = 0; 100 if(op == '+') c = a + b; 101 else if(op == '-') c = a -b; 102 else if(op == '*') c = a * b; 103 else if(op == '/') c = a / b; 104 stack[top] = c; 105 } 106 ++i; 107 } 108 if(top < 0) return 0; 109 else return stack[top]; 110 } 111 112 int main(int argc, char *argv[]){ 113 char *parms = "-20.5+(100-(3+2)*8)/(8-5) - 10"; 114 //char *parms = "10+100/2*5"; 115 data_top = -1; 116 op_top = -1; 117 num_top = -1; 118 mtoe(parms); 119 printf("\n"); 120 printf("%s = ",parms); 121 printf("%f\n",calculating()); 122 int i = 0; 123 for(i = 0; i <= data_top; i++){ 124 if(datas[i].op) printf("%c ", datas[i].op); 125 else printf("%f ",datas[i].num); 126 } 127 printf("\n\n"); 128 return 0; 129 }