2 条题解

  • 0
    @ 2024-8-12 15:34:56

    无法处理负数以及除数为0的情况:

    #include <bits/stdc++.h>
    using namespace std;
    using ll = long long;
    
    // 运算符优先级映射
    map<char,int> mp;
    // 操作符栈
    stack<char> op;
    // 操作数栈
    stack<ll> num;
    
    // eval: 执行一次计算,将栈顶的两个操作数和一个运算符出栈,计算结果入栈
    void eval(){
        ll a = num.top(); num.pop(); // 取出右操作数
        ll b = num.top(); num.pop(); // 取出左操作数
        char c = op.top(); op.pop(); // 取出运算符
        switch(c){
            case '+': num.push(b + a); break; // 加法
            case '-': num.push(b - a); break; // 减法
            case '*': num.push(b * a); break; // 乘法
            case '/': num.push(b / a); break; // 整数除法
            case '^': num.push(pow(b, a)); break; // 幂运算
        }
    }
    
    int main(){
        // 设置运算符的优先级,数字越大优先级越高
        mp['+'] = 1;
        mp['-'] = 1;
        mp['*'] = 2;
        mp['/'] = 2;
        mp['^'] = 3;
    
        string str;
        // 读取整个输入表达式(不包含空格)
        cin >> str;
    
        ll k = 0;              // 临时保存当前多位数字
        bool flag = false;     // 标记上一个字符是否为数字
    
        // 遍历表达式字符
        for(char cc : str){
            if(isdigit(cc)){
                // 如果是数字字符,则累加到当前数字 k 中
                k = k * 10 + (cc - '0');
                flag = true;
                continue;
            }
            // 如果上一个字符是数字,且当前字符不是数字,则将之前累积的数字入栈
            if(flag){
                num.push(k);
                k = 0;       // 重置 k
                flag = false; // 重置标记
            }
            if(cc == '('){
                // 左括号直接入栈
                op.push(cc);
            }
            else if(cc == ')'){
                // 遇到右括号,依次计算直到遇到左括号
                while(op.top() != '('){
                    eval();
                }
                op.pop(); // 弹出左括号
            }
            else {
                // 如果是运算符,则根据优先级决定是否先计算栈中的运算
                while(!op.empty() && mp[op.top()] >= mp[cc]){
                    eval();
                }
                op.push(cc);
            }
        }
        // 处理最后一个数字(如果有)
        if(flag){
            num.push(k);
        }
        // 处理栈中剩余的运算
        while(!op.empty()){
            eval();
        }
    
        // 最终结果在 num 栈顶
        ll res = num.top();
        cout << res;
        return 0;
    }
    
    • 0
      @ 2024-8-12 15:33:43

      可以正确处理负数的:

      #include <bits/stdc++.h>
      using namespace std;
      using ll = long long;
      map<char, int> mp;
      stack<char> op;
      stack<ll> num;
      void eval() {
          ll a = num.top(); num.pop();
          ll b = num.top(); num.pop();
          char c = op.top(); op.pop();
          switch (c) {
              case '+': num.push(b + a); break;
              case '-': num.push(b - a); break;
              case '*': num.push(b * a); break;
              case '/': 
                  if (a == 0) {
                      cerr << "Error: Division by zero!" << endl;
                      exit(1);
                  }
                  num.push(b / a); 
                  break;
              case '^': num.push(pow(b, a)); break;
          }
      }
      int main() {
          mp['+'] = 1; mp['-'] = 1;
      	mp['*'] = 2;mp['/'] = 2;
          mp['^'] = 3;
          string str;
          cin >> str;
          int k = 0;   // 用来取得字符串中的数
          bool flag = false;   // 标记是否为数字, 默认为否
          bool negative = false; // 标记是否为负数
      
          for (int i = 0; i < str.length(); ++i) {
              char cc = str[i];
              
              if (cc == '-' && (i == 0 || str[i-1] == '(' || mp.count(str[i-1]))) {
                  // 如果是负号的情况:在开头、左括号后或另一个运算符后
                  negative = true;
                  continue;
              }
      
              if (isdigit(cc)) {        
                  k = k * 10 + cc - '0';
                  flag = true;
                  continue;
              }
              
              if (flag) {  // 如果当前是一个数字,处理它
                  if (negative) {
                      k = -k;  // 如果是负数,将其取负
                      negative = false;
                  }
                  num.push(k);
                  k = 0;             // 数字进栈后,k恢复到初始值:0 
                  flag = false;   // 数字进栈后,flag恢复为非数字 
              }
              if (cc == '(') {
                  op.push(cc);
              } else if (cc == ')') {
                  while (!op.empty() && op.top() != '(') {
                      eval();
                  }
                  op.pop(); // 弹出 '('
              } else {
                  while (!op.empty() && mp[op.top()] >= mp[cc]) eval();
                  op.push(cc);
              }
          }  
          if (flag) { // 处理最后的数字
              if (negative) {
                  k = -k;  // 如果是负数,将其取负
              }
              num.push(k);
          }   
          while (!op.empty()) {
              eval();
          }
          ll res = num.top();
          cout << res << endl;
          return 0;
      }
      
      • 1

      信息

      ID
      834
      时间
      1000ms
      内存
      256MiB
      难度
      8
      标签
      递交数
      56
      已通过
      10
      上传者