今天在csdn student 大本营看到了一个人家写的24程序,感觉人家的思路非常清晰,于是自己也着手写了一个,顺便温习了一下标准c++。在我的程序中,使用了 stringstream类做parse,后缀表达式穷举所有可行解,而用中缀表达式计算用户输入的表达式。因为比较懒,当用户算不出来时,按出来的答案是个后缀表达式。 有关源代码如下:
Token.h :用于Parse,以及操作符,优先级的定义
01#ifndef TOKEN_H
02#define TOKEN_H
03enum Token_type {Numeric = 0,Op};
04enum Operator{ADD_OPR = 0,MINUS_OPR,
05MUL_OPR,DIV_OPR,
06LEFT_BRA,RIGHT_BRA,
07TER};
08enum PRI{HIGHER = 0,LOWER,EQUAL,NO_POSSIBLE};
09class Token
10{
11public:
12 Token(Token_type _type,double _x,Operator _op):type(_type),
13 x(_x),op(_op){}
14 Token_type type;
15 double x;
16 Operator op;
17};
18void Parse(string expression,vector
& tokens);
19bool isOp(char c);
20#endif
Token.cpp
01#include
02#include
03#include
04using namespace std;
05#include "Token.h"
06extern int OpTypeNum;
07char operators[7] = {'+','-','*','/','(',')','#'};
08
09bool isOp(char c,int &index)
10{
11 for (int i = 0;i < OpTypeNum;i++)
12 {
13 if (c == operators[i])
14 {
15 index = i;
16 return true;
17 }
18 }
19 return false;
20}
21void Parse(string expression,vector
& tokens)
22{
23 stringstream ss (stringstream::in | stringstream::out);
24 ss << expression;
25 char c;
26 int val,index;
27 while (ss >> c)
28 {
29 if (isdigit(c))
30 {
31 ss.putback(c);
32 ss >> val;
33 tokens.push_back(Token(Numeric,val,Operator(0)));
34 }else if (isOp(c,index))
35 tokens.push_back(Token(Op,-1,Operator(index)));
36 }
37}
ExpCalc.h 用堆栈实现的中缀和后缀表达式的计算
01#ifndef EXPCALC_H
02#define EXPCALC_H
03class ExpCalc
04{
05public:
06 bool PostfixCalc(vector
&a,vector
&ops,double & res);
07 bool infixCalc(vector
& tokens,double& res);
08 bool Calc(double x1,double x2,Operator op,double & res);
09 void Clear();
10private:
11 bool doWhenHigher(Operator op);
12 bool doWhenLower(Operator op,Operator nxt_op);
13 bool doWhenEqual();
14
15 stack
operands_stack;
16 stack
operators_stack;
17};
18#endif
ExpCalc.cpp
001#include
002#include
003#include
004using namespace std;
005#include "Token.h"
006#include "ExpCalc.h"
007#include "24Game.h"
008int OpTypeNum = 7;