計算表達值模板

namespace cal_expression{
    int level[300];
    bool f;
    ///設置優先級
    inline void init() {
        level['*'] = level['/'] = 2;
        level['+'] = level['-'] = 1;
        f = true;
    }
    ///加空格
    inline string add_blank(string s) {
        string t;
        for (int i = 0; i < s.size(); ++i) {
            if(isdigit(s[i])) t += s[i];
            else {
                t += ' ';
                t += s[i];
                t += ' ';
            }
        }
        return t;
    }
    inline string convert(string s) {  // 把中綴表達式轉換爲後綴表達式
      stack<char> oper;
      stringstream ss;
      ss << s;
      string t, tmp;
      while (ss >> tmp) {
        if (isdigit(tmp[0]))
          t += tmp + " ";  // 1. 若是遇到一個數,輸出該數
        else if (tmp[0] == '(')
          oper.push(tmp[0]);       // 2. 若是遇到左括號,把左括號入棧
        else if (tmp[0] == ')') {  // 3. 若是遇到右括號,
          while (!oper.empty() && oper.top() != '(')
            t += string(1, oper.top()) + " ",
                oper.pop();  // 不斷取出棧頂並輸出,直到棧頂爲左括號,
          oper.pop();        // 而後把左括號出棧
        } else {             // 4. 若是遇到運算符
        while (!oper.empty() && level[oper.top()] >= level[tmp[0]])
            t += string(1, oper.top()) + " ",
                oper.pop();  // 只要棧頂符號的優先級不低於新符號,就不斷取出棧頂並輸出
          oper.push(tmp[0]);  // 最後把新符號進棧
        }
      }
      while (!oper.empty()) t += string(1, oper.top()) + " ", oper.pop();
      return t;
    }

    inline int calc(string s) {  // 計算轉換好的後綴表達式
      stack<int> num;
      stringstream ss;
      ss << s;
      string t, tmp;
      while (ss >> tmp) {
        if (isdigit(tmp[0]))
          num.push(stoi(tmp));
        else {
          int b, a;  // 取出棧頂元素,注意順序
          if (!num.empty()) b = num.top();
          num.pop();
          if (!num.empty()) a = num.top();
          num.pop();
          if (tmp[0] == '+') num.push(a + b);
          if (tmp[0] == '-') num.push(a - b);
          if (tmp[0] == '*') num.push(a * b);
          if (tmp[0] == '/') {
                if(b && a%b == 0) num.push(a / b);
                else num.push(555), f = false;
          }
        }
      }
      return num.top();
    }
    inline int solve(string s) {
        init();
        int v = calc(convert(add_blank(s)));
        if(f) return v;
        else return -1;
    }
}
相關文章
相關標籤/搜索