Four simple arithmetic calculator

  1 #include <string>
  2 #include <stack>
  3 #include <vector>
  4 
  5 class Element {
  6 public:
  7     static Element MakeData(double value_) {return Element(DATA, value_, ' ');}
  8     static Element MakeOp(char op) {return Element(OP, 0.0, op);}
  9     bool isData() const { return t == DATA; }
 10     bool isOp() const { return t == OP; }
 11     char getOp() const { return op;}
 12     double getValue() const { return value; }
 13     int priority() const {
 14         if (isOp()) {
 15             if (getOp() == '*' || getOp() == '/') {
 16                 return 2;
 17             } else if (getOp() == '+' || getOp() == '-') {
 18                 return 1;
 19             } else if (getOp() == '(' || getOp() == ')') {
 20                 return 0;
 21             }
 22         }
 23         return -1;
 24     }
 25 private:
 26     enum Type {DATA, OP};
 27     Type t;
 28     double value;
 29     char op;
 30     Element(Type t_, double value_, char op_) : t(t_), value(value_), op(op_) {}
 31  };
 32 
 33 bool isOp(char c) {
 34     return c == '+' || c == '-' || c == '*' || c == '/' || c == '(' || c == ')';
 35 }
 36 
 37 using std::string;
 38 using std::vector;
 39 using std::stack;
 40 
 41 vector<Element> str2mid(const string &input) {
 42     vector<Element> mid;
 43     string data;
 44     for (size_t i = 0; i < input.length(); i++) {
 45         if (isOp(input[i])) {
 46             if (data != "") {
 47                 mid.push_back(Element::MakeData(std::stod(data)));
 48                 data = "";
 49             }
 50             mid.push_back(Element::MakeOp(input[i]));
 51         } else if (!isspace(input[i])){
 52             data += input[i];
 53         }
 54     }
 55     if (data != "") {
 56         mid.push_back(Element::MakeData(std::stod(data)));
 57         data = "";
 58     }
 59     return MID;
 60  }
 61 is  
62 is Vector <the Element> mid2post ( const Vector <the Element> & MID) {
 63 is      Stack <the Element> S;
 64      Vector <the Element> POST;
 65      for (IT = mid.begin Auto (); IT! mid.end = (); IT ++ ) {
 66          IF (IT-> isData ()) { // if the operand is directly outputs 
67              post.push_back (* IT);
 68          } the else  IF (IT-> Isop () IT- &&> getOp () == ' ( ' ) { // If '('Direct push 
69             s.push (* IT);
 70          } the else  IF (IT-> Isop () && IT-> getOp () == ' ) ' ) { // If '') to the stack operator '(' after the stack 
71 is              the while (s.empty () && s.top () getOp () =!.! ' ( ' ) {
 72                  post.push_back (s.top ());
 73 is                  s.pop ();
 74              }
 75              s.pop ();
 76          } the else  IF (IT-> Isop ()) { // if the operator from the stack until the stack is lower than the priority of the operator, where '(' the lowest priority, then the operator stack 
77              the while(!s.empty() && s.top().priority() >= it->priority()) {
 78                 post.push_back(s.top());
 79                 s.pop();
 80             }
 81             s.push(*it);
 82         }
 83     }
 84     while(!s.empty()) { // 栈中元素全部出栈
 85         post.push_back(s.top());
 86         s.pop();
 87     }
 88     return post;
 89 }
 90 
 91 double calc_post(const vector<Element> &post) {
 92     stack<Element> s;
 93     for (auto it = post.begin(); it != post.end(); it++) {
 94         if (it->isData()) {
 95             s.push(*it);
 96         } else if (it->isOp()) {
 97             double op_2 = s.top().getValue();
 98             s.pop();
 99             double op_1 = 0;
100             if (!s.empty()) { //处理开头为-的情况
101                 op_1 = s.top().getValue();
102                  s.pop ();    
103              }
 104              char on it- => getOp ();
105              if (on == ' + ' ) {
 106                  s.push (Element Make :: Data (op_1 + op_2));
107              } else  if (at == ' - ' ) {
 108                  s.push (Element Make :: Data (op_1 - op_2));
109              } else  if (on == ' * ' ) {
 110                 s.push(Element::MakeData(op_1 * op_2));
111             } else if (op == '/') {
112                 s.push(Element::MakeData(op_1 / op_2));
113             }
114         }
115     }
116     return s.top().getValue();
117 }
118 
119 double calc(const std::string &input) {
120     return calc_post(mid2post(str2mid(input)));
121 }

 

Guess you like

Origin www.cnblogs.com/ren-yu/p/11222749.html