但為保持原汁原味,至今未做改進,供大家參考
主要的兩個小技巧:
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

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16



17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

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

2

3

4

5

6

7

8

9

10

11

12

13

14



15

16

17

18

19

20

21

22



23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41



42

43

44

45



46

47

48

49

50

51

52

53



54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77



78

79

80

81

82

83

84



85

86



87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106



107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124



125

126

127

128

129

130

131



132

133

134

135

136



137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166



167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200



201

202



203



204



205



206



207



208



209



210

211

212

213

214

215

216

217



218

219

220

221

222

223

224

225

226



227

228

229

230



231

232

233

234

235

236

237

238



239

240

241

242



243

244

245

246

247

248

249

250

251

252

253

254



255

256



257

258

259

260

261

262



263

264

265

266

267



268



269

270

271

272

273



274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307



308

309

310

311



312

313

314

315

316

317

318

319

320

321

322

323

324

325

326



327

328

329

330

331

332

333

334

335

336

337

338

339

340

341

342

343

344

345

346



347

348

349

350

351

352

353

354

355

356

357

358

359



360

361

362

363



364

365

366

367

368



369

370

371

372

373

374

375

376

377

378

379

380

381

382

383

384

385

386

387

388

389

390
