利用栈进行表达式的求值

  1 #include <stdio.h>
2 #include <string.h>
3 #include <stdlib.h>
4 #include <ctype.h>
5 #include <stack>
6 usingnamespace std;
7
8 stack<float> OperandStack;
9 stack<char> OperatorStack;
10
11 char priority[]={'(', ')', '', '+', '-', '', '*', '/'};
12
13 int GetPriority(char ch, char top)
14 {//这里用了点小技巧,通过在priority数组中添加多余的字符,可以仅通过相减来简化优先级的判断
15 int a, b;
16 for(int i =0; i <8; i++)
17 {
18 if( ch == priority[i] )
19 a = i;
20 if( top == priority[i] )
21 b = i;
22 }
23 if( a - b <=1)
24 return0;
25 else
26 return1;
27 }
28
29 float compute(float p, float q, char c)
30 {
31 switch(c)
32 {
33 case'+':
34 return p+q;
35 case'-':
36 return p-q;
37 case'*':
38 return p*q;
39 case'/':
40 return p/q;
41 }
42
43 }
44
45 float ComputeResult(char suffix[])
46 {
47 float f, op1, op2, tmp;
48 char*t = strtok(suffix, "");
49 while( t != NULL )
50 {
51 if( isdigit(t[0]) )
52 {//将字符串转化为浮点数
53 f = atof(t);
54 OperandStack.push(f);
55 }
56 else
57 {//利用栈进行计算
58 op2 = OperandStack.top();
59 OperandStack.pop();
60 op1 = OperandStack.top();
61 OperandStack.pop();
62 tmp = compute(op1, op2, t[0]);
63 OperandStack.push(tmp);
64 }
65 t = strtok(NULL, "");
66 }
67 f = OperandStack.top();
68 OperandStack.pop();
69 return f;
70 }
71
72 int main()
73 {
74 char expression[100] ="12.04 / 4 - 3 / 2 * 6 - 6 / ( 4 - 3.5 + 1 / 2 )";
75 char suffix[100];
76 char*ptr = suffix;
77 int opr; //操作数
78 char opt; //运算符
79
80 char*t = strtok(expression,"");
81
82 while( t != NULL)
83 {
84 if( isdigit(t[0]) )
85 {//如果是数字则直接进入后缀表达式
86 strcpy( ptr, t);
87 ptr = ptr + strlen( t ) +1;
88 *(ptr -1) ='';
89 t = strtok(NULL, ""); //取下一个操作符或数
90 }
91 else
92 {//否则就是运算符,需进行栈区的判断
93 opt = t[0]; //取运算符
94 if( opt =='(' ) //直接入栈
95 {
96 OperatorStack.push(opt);
97 t = strtok(NULL, ""); //取下一个操作符或数
98 }
99 elseif( opt ==')' )
100 {//退栈至左括号
101 if( OperatorStack.top() !='(')
102 {
103 *ptr = OperatorStack.top();
104 *(ptr +1)='';
105 ptr +=2;
106 OperatorStack.pop();//弹出栈顶运算符
107 }
108 else
109 {
110 OperatorStack.pop();//弹出(运算符
111 t = strtok(NULL, ""); //取下一个操作符或数
112 }
113 }
114 elseif( OperatorStack.empty() || GetPriority(opt, OperatorStack.top()) ==1 )
115 {//如果当前运算符优先级高于栈顶 或 栈为空
116 OperatorStack.push(opt); //入栈
117 t = strtok(NULL, ""); //取下一个操作符或数
118 }
119 else
120 {//如果低于或者等于
121 *ptr = OperatorStack.top();
122 *(ptr +1)='';
123 ptr +=2;
124 OperatorStack.pop();
125 }
126 }
127 }
128 //弹出最后栈中残留的操作符,并对suffix做结尾处理
129 while( !OperatorStack.empty() )
130 {
131 *ptr = OperatorStack.top();
132 *(++ptr) ='';
133 ptr++;
134 OperatorStack.pop();
135 }
136 *(ptr -1) ='\0';
137 //输出后缀表达
138 printf("%s\n", suffix);
139 //计算结果
140 float r = ComputeResult(suffix);
141 printf("%f\n", r);
142
143 return0;
144 }

虽说表达式求值的算法不难理解。但是很容易出现算法细节上的认识错误。

另外实现起来,也有众多的问题需要考虑。比如字符串和浮点数的相互转化~字符型变量与浮点变量的区别对待~还有字符串的分割处理~包括优先级的判断技巧等等~

总之,当初俺学的时候试图实现,最后失败了。如今备考研究生,编程水平自有提升,有机会拿出来仔细写一写,复习下也不错~

posted @ 2011-08-18 23:01  IT屁民  阅读(748)  评论(0编辑  收藏  举报