这是我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
9
using namespace std;
10
11
typedef stack<double> STACK_DOUBLE;
12
typedef stack<char> STACK_CHAR;
13
14
15
class 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
9
using namespace std;
10
11
12
//检查表达式是否合法
13
int CCalculator::CheckString(CString csExp )
14

{
15
16
return 1;
17
18
};
19
20
//计算合法表达式的值
21
double 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
//对不合法的表达式,找到错误,通知用户修改
123
int CCalculator::ReturnError(CString csExp)
124

{
125
return 1;
126
127
};
128
129
//查找运算符优先级
130
char 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
//初始化运算符优先级列表
199
char 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
//构造函数
216
CCalculator::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
//判断是否为运算符
253
int 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
//四则运算函数,返回结果
306
double 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
//从表达式的当前位置查找操作数并返回,当前位置向前移动
345
double 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
乖狗狗 阅读(2602)
评论(7) 编辑 收藏 引用