表达式求解问题
第四次数据结构实验:
实验三:表达式求值
实验目的:
1、掌握顺序栈结点类型的定义
2、掌握栈的插入和删除结点操作的特点;
3、熟悉对栈的一些基本操作和具体的函数定义。
代码:
1
/*
Status.h 各种常量状态、结构体的声明文件
*/
2 #pragma once
3 #include < malloc.h >
4 #include < stdlib.h >
5
6 #define TRUE 1
7 #define FALSE 0
8 #define OK 1
9 #define ERROR 0
10 #define OVERFLOW -2
11 #define INFEASIBLE -1
12
13 typedef int Status;
14
15 typedef char SElemType;
16 #define STACK_INIT_SIZE 100
17 #define STACKINCREMENT 10
18 struct SqStack{
19 SElemType * base ;
20 SElemType * top;
21 int stacksize;
22 };
23
24 typedef char QElemType;
25 #define MAXQSIZE 100
26 struct SqQueue{
27 QElemType * base ;
28 int front;
29 int rear;
30 };
31
32 /* SqStack.h CSqStack类的声明文件 */
33 #pragma once
34 #include " Status.h "
35
36 class CSqStack
37 {
38 private :
39 // 栈数据结构
40 SqStack S;
41 public :
42 CSqStack( void );
43 ~ CSqStack( void );
44 // 压栈
45 Status Push(SElemType e);
46 // 出栈
47 Status Pop(SElemType & e);
48 // 返回栈顶元素,非弹出
49 char GetTop();
50 // 判断是否为空
51 bool Empty();
52 private :
53 // 初始化栈数据结构,放在构造函数里,私有了..
54 Status InitStack();
55 };
56 /* SqStack.h CSqStack类的定义文件 */
57 #include " SqStack.h "
58
59 CSqStack::CSqStack( void )
60 {
61 this -> InitStack();
62 }
63
64 CSqStack:: ~ CSqStack( void )
65 {
66 free( this -> S. base );
67 }
68
69 // 压栈
70 Status CSqStack::Push(SElemType e)
71 {
72 if (S.top - S. base >= S.stacksize)
73 {
74 S. base = (SElemType * )realloc(S. base ,(S.stacksize + STACKINCREMENT) * sizeof (SElemType));
75 if ( ! S. base )
76 exit(OVERFLOW);
77 S.top = S. base + S.stacksize;
78 S.stacksize += STACKINCREMENT;
79 }
80 * S.top ++ = e;
81
82 return OK;
83 }
84
85 // 出栈
86 Status CSqStack::Pop(SElemType & e)
87 {
88 if (S.top == S. base )
89 return ERROR;
90 e = *-- S.top;
91
92 return OK;
93 }
94
95 // 返回栈顶元素,非弹出
96 char CSqStack::GetTop()
97 {
98 if (S.top == S. base )
99 return ' ' ;
100
101 return * (S.top - 1 );
102 }
103
104 // 判断是否为空
105 bool CSqStack::Empty()
106 {
107 return S.top == S. base ? TRUE : FALSE ;
108 }
109
110 // 初始化栈数据结构,放在构造函数里,私有了..
111 Status CSqStack::InitStack()
112 {
113 S. base = (SElemType * )malloc(STACK_INIT_SIZE * sizeof (SElemType));
114 if ( ! S. base )
115 exit(OVERFLOW);
116 S.top = S. base ;
117 S.stacksize = STACK_INIT_SIZE;
118
119 return OK;
120 }
121
122 /*
123 ///
124 Main.cpp
125 main函数所在文件
126 0x0o@Live.Cn
127 08.11.05
128 Vista-U + VS2008 下编译通过.
129
130 */
131
132 #include < iostream >
133 #include " Status.h "
134 #include " SqStack.h "
135 using namespace std;
136
137 char Operate( char a, char ch, char b)
138 {
139 switch (ch)
140 {
141 case ' + ' :
142 return a + b - 48 ;
143 case ' - ' :
144 return a - b + 48 ;
145 case ' * ' :
146 return (a - 48 ) * (b - 48 ) + 48 ;
147 case ' / ' :
148 return (a - 48 ) / (b - 48 ) + 48 ;
149 }
150 }
151
152 char Precede( char ch1, char ch2)
153 {
154 if (ch1 == ch2 && ch2 == ' # ' )
155 return ' = ' ;
156 if (ch1 == ch2 && ch1 != ' # ' )
157 return ' > ' ;
158 if (ch1 == ' # ' )
159 return ' < ' ;
160 if (ch1 == ' ( ' && ch2 == ' ) ' )
161 return ' = ' ;
162 if (ch1 == ' ( ' || ch2 == ' ( ' )
163 return ' < ' ;
164 if (ch2 == ' ) ' || ch1 == ' ) ' )
165 return ' > ' ;
166 if (ch1 == ' * ' || ch1 == ' / ' )
167 return ' > ' ;
168 if (ch2 == ' * ' || ch2 == ' / ' )
169 return ' < ' ;
170 else
171 return ' > ' ;
172 }
173
174 bool IsOpnd( char ch)
175 {
176 if ( ch >= 48 && ch <= 57 )
177 return TRUE;
178 else
179 return FALSE;
180 }
181
182 char EvaluateExpression(CSqStack & OPND,CSqStack & OPTR)
183 {
184 char ch;
185 ch = getchar();
186
187 while (ch != ' # ' || OPTR.GetTop() != ' # ' )
188 {
189 if (IsOpnd(ch))
190 {
191 OPND.Push(ch);
192 ch = getchar();
193 }
194 else
195 {
196 switch (Precede(OPTR.GetTop(),ch))
197 {
198 case ' < ' :
199 OPTR.Push(ch);
200 ch = getchar();
201 break ;
202 case ' = ' :
203 char x;
204 OPTR.Pop(x);
205 ch = getchar();
206 break ;
207 case ' > ' :
208 char theta,a,b;
209 OPTR.Pop(theta);
210 OPND.Pop(b);OPND.Pop(a);
211 OPND.Push(Operate(a,theta,b));
212 break ;
213 default :
214 cout << " Error! " << endl;
215 }
216 }
217 }
218
219 return OPND.GetTop();
220
221 }
222
223 int main()
224 {
225 char ch;
226 CSqStack OPTR,OPND;
227 cout << " Please Input The Expression: " << endl;
228
229 OPTR.Push( ' # ' );
230
231 ch = EvaluateExpression(OPND,OPTR);
232
233 cout << ( int )(ch - 48 ) << endl;
234
235
236 return 0 ;
237 }
238
2 #pragma once
3 #include < malloc.h >
4 #include < stdlib.h >
5
6 #define TRUE 1
7 #define FALSE 0
8 #define OK 1
9 #define ERROR 0
10 #define OVERFLOW -2
11 #define INFEASIBLE -1
12
13 typedef int Status;
14
15 typedef char SElemType;
16 #define STACK_INIT_SIZE 100
17 #define STACKINCREMENT 10
18 struct SqStack{
19 SElemType * base ;
20 SElemType * top;
21 int stacksize;
22 };
23
24 typedef char QElemType;
25 #define MAXQSIZE 100
26 struct SqQueue{
27 QElemType * base ;
28 int front;
29 int rear;
30 };
31
32 /* SqStack.h CSqStack类的声明文件 */
33 #pragma once
34 #include " Status.h "
35
36 class CSqStack
37 {
38 private :
39 // 栈数据结构
40 SqStack S;
41 public :
42 CSqStack( void );
43 ~ CSqStack( void );
44 // 压栈
45 Status Push(SElemType e);
46 // 出栈
47 Status Pop(SElemType & e);
48 // 返回栈顶元素,非弹出
49 char GetTop();
50 // 判断是否为空
51 bool Empty();
52 private :
53 // 初始化栈数据结构,放在构造函数里,私有了..
54 Status InitStack();
55 };
56 /* SqStack.h CSqStack类的定义文件 */
57 #include " SqStack.h "
58
59 CSqStack::CSqStack( void )
60 {
61 this -> InitStack();
62 }
63
64 CSqStack:: ~ CSqStack( void )
65 {
66 free( this -> S. base );
67 }
68
69 // 压栈
70 Status CSqStack::Push(SElemType e)
71 {
72 if (S.top - S. base >= S.stacksize)
73 {
74 S. base = (SElemType * )realloc(S. base ,(S.stacksize + STACKINCREMENT) * sizeof (SElemType));
75 if ( ! S. base )
76 exit(OVERFLOW);
77 S.top = S. base + S.stacksize;
78 S.stacksize += STACKINCREMENT;
79 }
80 * S.top ++ = e;
81
82 return OK;
83 }
84
85 // 出栈
86 Status CSqStack::Pop(SElemType & e)
87 {
88 if (S.top == S. base )
89 return ERROR;
90 e = *-- S.top;
91
92 return OK;
93 }
94
95 // 返回栈顶元素,非弹出
96 char CSqStack::GetTop()
97 {
98 if (S.top == S. base )
99 return ' ' ;
100
101 return * (S.top - 1 );
102 }
103
104 // 判断是否为空
105 bool CSqStack::Empty()
106 {
107 return S.top == S. base ? TRUE : FALSE ;
108 }
109
110 // 初始化栈数据结构,放在构造函数里,私有了..
111 Status CSqStack::InitStack()
112 {
113 S. base = (SElemType * )malloc(STACK_INIT_SIZE * sizeof (SElemType));
114 if ( ! S. base )
115 exit(OVERFLOW);
116 S.top = S. base ;
117 S.stacksize = STACK_INIT_SIZE;
118
119 return OK;
120 }
121
122 /*
123 ///
124 Main.cpp
125 main函数所在文件
126 0x0o@Live.Cn
127 08.11.05
128 Vista-U + VS2008 下编译通过.
129
130 */
131
132 #include < iostream >
133 #include " Status.h "
134 #include " SqStack.h "
135 using namespace std;
136
137 char Operate( char a, char ch, char b)
138 {
139 switch (ch)
140 {
141 case ' + ' :
142 return a + b - 48 ;
143 case ' - ' :
144 return a - b + 48 ;
145 case ' * ' :
146 return (a - 48 ) * (b - 48 ) + 48 ;
147 case ' / ' :
148 return (a - 48 ) / (b - 48 ) + 48 ;
149 }
150 }
151
152 char Precede( char ch1, char ch2)
153 {
154 if (ch1 == ch2 && ch2 == ' # ' )
155 return ' = ' ;
156 if (ch1 == ch2 && ch1 != ' # ' )
157 return ' > ' ;
158 if (ch1 == ' # ' )
159 return ' < ' ;
160 if (ch1 == ' ( ' && ch2 == ' ) ' )
161 return ' = ' ;
162 if (ch1 == ' ( ' || ch2 == ' ( ' )
163 return ' < ' ;
164 if (ch2 == ' ) ' || ch1 == ' ) ' )
165 return ' > ' ;
166 if (ch1 == ' * ' || ch1 == ' / ' )
167 return ' > ' ;
168 if (ch2 == ' * ' || ch2 == ' / ' )
169 return ' < ' ;
170 else
171 return ' > ' ;
172 }
173
174 bool IsOpnd( char ch)
175 {
176 if ( ch >= 48 && ch <= 57 )
177 return TRUE;
178 else
179 return FALSE;
180 }
181
182 char EvaluateExpression(CSqStack & OPND,CSqStack & OPTR)
183 {
184 char ch;
185 ch = getchar();
186
187 while (ch != ' # ' || OPTR.GetTop() != ' # ' )
188 {
189 if (IsOpnd(ch))
190 {
191 OPND.Push(ch);
192 ch = getchar();
193 }
194 else
195 {
196 switch (Precede(OPTR.GetTop(),ch))
197 {
198 case ' < ' :
199 OPTR.Push(ch);
200 ch = getchar();
201 break ;
202 case ' = ' :
203 char x;
204 OPTR.Pop(x);
205 ch = getchar();
206 break ;
207 case ' > ' :
208 char theta,a,b;
209 OPTR.Pop(theta);
210 OPND.Pop(b);OPND.Pop(a);
211 OPND.Push(Operate(a,theta,b));
212 break ;
213 default :
214 cout << " Error! " << endl;
215 }
216 }
217 }
218
219 return OPND.GetTop();
220
221 }
222
223 int main()
224 {
225 char ch;
226 CSqStack OPTR,OPND;
227 cout << " Please Input The Expression: " << endl;
228
229 OPTR.Push( ' # ' );
230
231 ch = EvaluateExpression(OPND,OPTR);
232
233 cout << ( int )(ch - 48 ) << endl;
234
235
236 return 0 ;
237 }
238
以上代码存在问题!
很明显,用char来存输入的数据,如果100*2怎么办?弹出来的是0….太尴尬了
这个问题其实也挺好解决的,例如:堆栈的数据类型是int,然后把字符接收时处理,如果下一个还是数字,就把此数字×10+下一个数字,接受完的时候再存入堆栈即可..。
问题是这个代码的其它地方我还没跟踪明白,貌似构造的表达式出现某某现象时,最终结果是一个错误的数字…
哎,懒得改了..>
今天代码写的有点取巧了,明显用的就是回文序列里面的代码,复用果真很舒服,省了很多时间的说…。
--------by 0x0o
Time: 08.11.05 15:41