1 #include <string> 2 #include <stack> 3 #include <vector> 4 5 using std::string; 6 using std::vector; 7 using std::stack; 8 9 class Element { 10 public: 11 static Element MakeData(double value_) {return Element(DATA, value_, ' ');} 12 static Element MakeOp(char op) {return Element(OP, 0.0, op);} 13 bool isData() const { return t == DATA; } 14 bool isOp() const { return t == OP; } 15 char getOp() const { return op;} 16 double getValue() const { return value; } 17 int priority() const { 18 if (isOp()) { 19 if (getOp() == '*' || getOp() == '/') { 20 return 2; 21 } else if (getOp() == '+' || getOp() == '-') { 22 return 1; 23 } else if (getOp() == '(' || getOp() == ')') { 24 return 0; 25 } 26 } 27 return -1; 28 } 29 private: 30 enum Type {DATA, OP}; 31 Type t; 32 double value; 33 char op; 34 Element(Type t_, double value_, char op_) : t(t_), value(value_), op(op_) {} 35 }; 36 37 bool isOp(char c) { 38 return c == '+' || c == '-' || c == '*' || c == '/' || c == '(' || c == ')'; 39 } 40 41 // 判断当前的 + - 是否为单目操作符 比如 (-3) 42 bool isSign(const string &input, size_t i) { 43 char c = input[i]; 44 if (c == '+' || c == '-') { 45 if (i == 0) { 46 return true; 47 } 48 if (input[i - 1] == '(') { 49 return true; 50 } 51 } 52 return false; 53 } 54 55 vector<Element> str2mid(const string &input) { 56 vector<Element> mid; 57 string data; 58 for (size_t i = 0; i < input.length(); i++) { 59 if (isSign(input, i)) { 60 data += input[i]; 61 continue; 62 } 63 if (isOp(input[i])) { 64 if (data != "") { 65 mid.push_back(Element::MakeData(std::stod(data))); 66 data = ""; 67 } 68 mid.push_back(Element::MakeOp(input[i])); 69 } else if (!isspace(input[i])){ 70 data += input[i]; 71 } 72 } 73 if (data != "") { 74 mid.push_back(Element::MakeData(std::stod(data))); 75 data = ""; 76 } 77 return mid; 78 } 79 80 vector<Element> mid2post(const vector<Element> &mid) { 81 stack<Element> s; 82 vector<Element> post; 83 for (auto it = mid.begin(); it != mid.end(); it++) { 84 if (it->isData()) { // 如果是操作数,直接输出 85 post.push_back(*it); 86 } else if (it->isOp() && it->getOp() == '(') { // 如果是'('直接入栈 87 s.push(*it); 88 } else if (it->isOp() && it->getOp() == ')') { // 如果是')'将栈中'('之后的操作符出栈 89 while(!s.empty() && s.top().getOp() != '(') { 90 post.push_back(s.top()); 91 s.pop(); 92 } 93 s.pop(); 94 } else if (it->isOp()) { // 如果是操作符 出栈直到栈顶优先级低于该操作符,其中'('的优先级最低,然后把该操作符入栈 95 while(!s.empty() && s.top().priority() >= it->priority()) { 96 post.push_back(s.top()); 97 s.pop(); 98 } 99 s.push(*it); 100 } 101 } 102 while(!s.empty()) { // 栈中元素全部出栈 103 post.push_back(s.top()); 104 s.pop(); 105 } 106 return post; 107 } 108 109 double calc_post(const vector<Element> &post) { 110 stack<Element> s; 111 for (auto it = post.begin(); it != post.end(); it++) { 112 if (it->isData()) { 113 s.push(*it); 114 } else if (it->isOp()) { 115 double op_2 = s.top().getValue(); 116 s.pop(); 117 double op_1 = s.top().getValue(); 118 s.pop(); 119 char op = it->getOp(); 120 if (op == '+') { 121 s.push(Element::MakeData(op_1 + op_2)); 122 } else if (op == '-') { 123 s.push(Element::MakeData(op_1 - op_2)); 124 } else if (op == '*') { 125 s.push(Element::MakeData(op_1 * op_2)); 126 } else if (op == '/') { 127 s.push(Element::MakeData(op_1 / op_2)); 128 } 129 } 130 } 131 return s.top().getValue(); 132 } 133 134 double calc(const std::string &input) { 135 return calc_post(mid2post(str2mid(input))); 136 }