今天在大本营看到了一个人家写的24程序,感觉人家的思路非常清晰,于是自己也着手写了一个,顺便温习了一下标准c++。在我的程序中,使用了stringstream类做parse,后缀表达式穷举所有可行解,而用中缀表达式计算用户输入的表达式。因为比较懒,当用户算不出来时,按出来的答案是个后缀表达式。
===============================================
4.21更新
1.发现对后缀表达式的理解错了。修改了穷举算24的函数,穷举空间改为4!*4^3 * 5,其中3个操作符在长度为7的后缀表达式的可能位置为5种。
2.使用二叉树和堆栈实现了后缀表达式向中缀的转化,可以给出算24的答案
3.加入了接受用户输入的4个数,也可以让系统产生四个数。
功能上已经比较完整了,用户界面上还不是很好,不过这个已经不是很重要的问题的。这部分代码,如果要做
图形界面,应该是很好移过去的。
有关源代码如下:
Token.h :用于Parse,以及操作符,优先级的定义
- #ifndef TOKEN_H
- #define TOKEN_H
- enum Token_type {Numeric = 0,Op};
- enum Operator{ADD_OPR = 0,MINUS_OPR,
- MUL_OPR,DIV_OPR,
- LEFT_BRA,RIGHT_BRA,
- TER};
- enum PRI{HIGHER = 0,LOWER,EQUAL,NO_POSSIBLE};
- class Token
- {
- public:
- Token(){}
- Token(Token_type _type,double _x,Operator _op):type(_type),
- x(_x),op(_op){}
- Token_type type;
- double x;
- Operator op;
- };
- void Parse(string expression,vector<Token>& tokens);
- bool isOp(char c);
- #endif
Token.cpp
- #include <string>
- #include <vector>
- #include <sstream>
- using namespace std;
- #include "Token.h"
- extern int OpTypeNum;
- char operators[7] = { '+','-','*','/','(',')','#'};
- bool isOp(char c,int &index)
- {
- for (int i = 0;i < OpTypeNum;i++)
- {
- if (c == operators[i])
- {
- index = i;
- return true;
- }
- }
- return false;
- }
- void Parse(string expression,vector<Token>& tokens)
- {
- stringstream ss (stringstream::in | stringstream::out);
- ss << expression;
- char c;
- int val,index;
- while (ss >> c)
- {
- if (isdigit(c))
- {
- ss.putback(c);
- ss >> val;
- tokens.push_back(Token(Numeric,val,Operator(0)));
- }else if (isOp(c,index))
- tokens.push_back(Token(Op,-1,Operator(index)));
- }
- }
ExpCalc.h 用堆栈实现的中缀和后缀表达式的计算,以及后缀转化为中缀表达式的功能
- #ifndef EXPCALC_H
- #define EXPCALC_H
- class tree_Node
- {
- public:
- tree_Node(){}
- ~tree_Node();
- void Print();
- tree_Node(tree_Node * _left,tree_Node * _right,Token _token):
- left(_left),right(_right),token(_token){}
- tree_Node * left;
- tree_Node * right;
- Token token;
- };
- class ExpCalc
- {
- public:
- void ShowInfixExp(vector<Token>& tokens);
- bool PostfixCalc(vector<Token> & tokens,double & res);
- bool infixCalc(vector<Token>& tokens,double& res);
- bool Calc(double x1,double x2,Operator op,double & res);
- void Clear();
- private:
- bool doWhenHigher(Operator op);
- bool doWhenLower(Operator op,Operator nxt_op);
- bool doWhenEqual();
- stack<double> operands_stack;
- stack<Operator> operators_stack;
- };
- #endif
ExpCalc.cpp
- #include <stack>
- #include <vector>
- #include <cmath>
- #include <iostream>