计算表达值模板

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;
    }
}

 

posted @ 2019-05-18 21:21  Wisdom+.+  阅读(212)  评论(0编辑  收藏  举报