这是我2005年初学C++时的一个小作品,虽然很不好
但为保持原汁原味,至今未做改进,供大家参考
主要的两个小技巧:
1是对e的处理
2是对负号的处理
开发环境:VC++ 7.0
Calculator.h : 头文件
1// Calculator.h : 头文件
2//
3#ifndef CALCULATOR_H_2005_04_27__
4#define CALCULATOR_H_2005_04_27__
5
6
7#include <stack>
8
9using namespace std;
10
11typedef stack<double> STACK_DOUBLE;
12typedef stack<char> STACK_CHAR;
13
14
15class CCalculator
16{
17 public :
18 double CountResult(CString csExp);
19 int CheckString(CString csExp);
20 int ReturnError(CString csExp);
21 CCalculator(void);
22
23 private:
24 STACK_DOUBLE m_doubleStack; //操作数栈
25 STACK_CHAR m_charStack; //操作符号栈
26 static char m_priTable[8][8]; //运算符优先级列表
27
28 char QueryPri(char chOperator1,char chOperator2);
29 //查找运算符优先级
30
31 //int JudgeOperator(char ch);
32 // //判断是否为操作符号
33
34 int JudgeOperator(CString csExp, int iLocation);
35 //判断是否为操作符号
36
37 double Count(double dbNum1,double dbNum2, char chOper);
38 //四则运算函数,返回计算结果
39
40 double GetCurrentDouble(CString csExpression,int& iCurrentLocation);
41 //从表达式的当前位置查找操作数并返回,当前位置向前移动
42
43
44};
45
46
47#endif
48
49 Calculator.cpp
1//Calculator.cpp
2
3
4#include "stdafx.h"
5#include "Calculator.h"
6#include <stack>
7#include <math.h>
8
9using namespace std;
10
11
12//检查表达式是否合法
13int CCalculator::CheckString(CString csExp )
14{
15
16 return 1;
17
18};
19
20//计算合法表达式的值
21double CCalculator::CountResult(CString csExp)
22{
23 int i = 0;
24 int j = 0;
25 int iLength = 0;
26 int& alia_i = i;
27 char chMyOperator = '\0';
28 char chCompareResult = '\0';
29 char chCurrent = '\0';
30 char chTop = '\0';
31 double dbNumber1 = 0.0;
32 double dbNumber2 = 0.0;
33 double dbResult = 0.0;
34 double dbCurrentNumber = 0.0;
35
36 csExp += "#";
37 iLength = csExp.GetLength(); //获取表达式的长度
38 m_charStack.push('#');
39
40 for (i=0; i<=iLength; )
41 {
42 chCurrent = csExp[i];
43
44 if ( JudgeOperator(csExp,i) ) //如果为操作符
45 {
46 //比较当前操作符与栈顶操作符的优先级
47 chTop = m_charStack.top();
48 chCompareResult = QueryPri(chCurrent, chTop);
49
50
51 switch (chCompareResult)
52 //根据比较结果执行不同的操作
53 {
54 case '>' :
55 //当前操作符优先级较高,压入操作符号栈
56 m_charStack.push(chCurrent);
57 i++;
58 break;
59
60 case '<' :
61 //当前操作符优先级较小,计算前面的运算结果
62 chMyOperator = m_charStack.top();
63 m_charStack.pop();
64 dbNumber2 = m_doubleStack.top();
65 m_doubleStack.pop();
66 dbNumber1 = m_doubleStack.top();
67 m_doubleStack.pop();
68 dbResult = Count(dbNumber1, dbNumber2, chMyOperator);
69 m_doubleStack.push(dbResult);
70 break;
71
72 case '=' :
73 //当前操作符与栈顶操作符优先级相同,有两种可能
74
75 if (chCurrent==')')
76 //如果为左右括号相遇,脱括号
77 {
78 m_charStack.pop();
79 i++;
80 break;
81 }//end if
82 else
83 //如果为两个'#'相遇,运算结束
84 {
85 if (chCurrent=='#')
86 {
87 dbResult = m_doubleStack.top();
88 return dbResult;
89 break;
90 }//end if
91
92 }//end else
93
94 case 'E' :
95 //比较出错
96 break;
97
98 default:
99 break;
100
101 }//end switch
102
103
104 }//end if
105 else
106 {
107 dbCurrentNumber = GetCurrentDouble(csExp,alia_i);
108 m_doubleStack.push(dbCurrentNumber);
109
110 }//end else
111
112 }//end for
113
114
115 return dbResult;
116
117
118
119};
120
121
122//对不合法的表达式,找到错误,通知用户修改
123int CCalculator::ReturnError(CString csExp)
124{
125 return 1;
126
127};
128
129//查找运算符优先级
130char CCalculator::QueryPri (char chOperator1, char chOperator2)
131{
132 int i = 0;
133 int j = 0;
134
135 switch (chOperator1)
136 {
137 case '+':
138 i = 0;
139 break;
140 case '-':
141 i = 1;
142 break;
143 case '*':
144 i = 2;
145 break;
146 case '/':
147 i = 3;
148 break;
149 case '(':
150 i = 4;
151 break;
152 case ')':
153 i = 5;
154 break;
155 case '#':
156 i = 6;
157 break;
158 case 'e':
159 i = 7;
160 break;
161 default:
162 break;
163 };
164
165 switch (chOperator2)
166 {
167 case '+':
168 j = 0;
169 break;
170 case '-':
171 j = 1;
172 break;
173 case '*':
174 j = 2;
175 break;
176 case '/':
177 j = 3;
178 break;
179 case '(':
180 j = 4;
181 break;
182 case ')':
183 j = 5;
184 break;
185 case '#':
186 j = 6;
187 break;
188 case 'e':
189 j = 7;
190 break;
191 default:
192 break;
193 };
194
195 return m_priTable[i][j];
196};
197
198//初始化运算符优先级列表
199char CCalculator::m_priTable[8][8] =
200{
201 //+,,,-,,,*,,,/,,,(,,,),,,#,,,e,
202 {'<','<','<','<','>','E','>','<'}, //+
203 {'<','<','<','<','>','E','>','<'}, //-
204 {'>','>','<','<','>','E','>','<'}, //*
205 {'>','>','<','<','>','E','>','<'}, /**////
206 {'>','>','>','>','>','E','>','E'}, //(
207 {'<','<','<','<','=','E','E','<'}, //)
208 {'<','<','<','<','<','<','=','<'}, //#
209 {'>','>','>','>','>','E','>','E'} //e
210
211
212
213};
214
215//构造函数
216CCalculator::CCalculator(void)
217{
218 int i = 0;
219
220 stack<double>::size_type double_Length;
221 stack<char>::size_type char_Length;
222
223
224 if (!(m_doubleStack.empty()))
225 //初始化操作数栈
226 {
227 double_Length = m_doubleStack.size();
228
229 for (i=1; i<=double_Length; i++)
230 {
231 m_doubleStack.pop();
232 }//end for
233 }//end if
234
235
236 if (!(m_charStack.empty()))
237 //初始化操作符号栈
238 {
239 char_Length=m_charStack.size();
240
241 for ( i=1; i<=char_Length; i++)
242 {
243 m_charStack.pop();
244 }//end for
245
246 }//end if
247
248};
249
250
251
252//判断是否为运算符
253int CCalculator::JudgeOperator(CString csExp, int iLocation)
254{
255 switch (csExp[iLocation])
256 {
257 case '+':
258 return 1;
259 break;
260 case '-':
261 if (iLocation==0)
262 {
263 return 0;
264 break;
265 }
266 else
267 { if ((csExp[iLocation-1]=='(') || (csExp[iLocation-1]=='e'))
268 {
269 return 0;
270 break;
271 }
272 else
273 {
274 return 1;
275 break;
276 }
277 }
278 return 1;
279 break;
280 case '*':
281 return 1;
282 break;
283 case '/':
284 return 1;
285 break;
286 case '(':
287 return 1;
288 break;
289 case ')':
290 return 1;
291 break;
292 case '#':
293 return 1;
294 break;
295 case 'e':
296 return 1;
297 break;
298 default :
299 return 0;
300 break;
301
302 };
303};
304
305//四则运算函数,返回结果
306double CCalculator::Count(double dbNum1, double dbNum2, char chOper)
307{
308 double dbResult = 0.0;
309
310 switch (chOper)
311 {
312 case '+':
313 dbResult = dbNum1 + dbNum2;
314 break;
315
316 case '-':
317 dbResult = dbNum1 - dbNum2;
318 break;
319
320 case '*':
321 dbResult = dbNum1 * dbNum2;
322 break;
323
324 case '/':
325 if (!(fabs(dbNum2 - 0.0) < 1e-6 ))
326 {
327 dbResult = dbNum1 / dbNum2;
328
329 }
330 break;
331
332 case 'e':
333 dbResult = dbNum1 * pow(10.0,dbNum2);
334 break;
335
336 default:
337 break;
338 };
339
340 return dbResult;
341
342};
343
344//从表达式的当前位置查找操作数并返回,当前位置向前移动
345double CCalculator::GetCurrentDouble(CString csExpression,int& iCurrentLocation)
346{
347 int i = 0;
348 int j = 0;
349 int iExpressionLength = 0;
350 int iELocation = 0;
351 CString csDoubleString("");
352 char chCurrentChar = '\0';
353 double dbNumber = 0.0;
354 i = iCurrentLocation;
355
356 iExpressionLength = csExpression.GetLength();
357
358 for ( j=i+1; j<iExpressionLength; )
359 {
360 chCurrentChar = csExpression[j];
361
362 if (!JudgeOperator(csExpression,j))
363 {
364 j++;
365
366 }//end if
367 else
368 {
369
370 break;
371
372
373 }//end else
374
375 }//end for
376
377 csDoubleString = csExpression.Mid(i, j-i);
378
379 dbNumber = atof(csDoubleString);
380
381
382
383 iCurrentLocation = j;
384
385 return dbNumber;
386
387
388};
389
390
posted on 2006-01-02 18:28
乖狗狗 阅读(2535)
评论(7) 编辑 收藏 引用