ZBLOG

#include #include #include #include class Express { private: std::string infix; public: Express(const std::string& exp) : infix(exp) {} bool isMatch() { std::stack s; for ...

在你的代码中,当输入的中缀表达式没有括号(如 1*1+1)时,转换为后缀表达式后生成了一个不正确的格式。出现这个问题的原因是在处理操作符和数字时,输出的格式没有正确处理空格,使得计算值时可能无法识别出操作数。

下面是对 Trans() 方法的一些修改,以确保后缀表达式的正确性,并且在运算时可以正确解析操作数。

#include <iostream>
#include <stack>
#include <sstream>
#include <string>

class Express {
private:
    std::string infix; 

public:
    Express(const std::string& exp) : infix(exp) {}

    bool isMatch() {
        std::stack<char> s;
        for (char ch : infix) {
            if (ch == '(') {
                s.push(ch);
            }
            else if (ch == ')') {
                if (s.empty() || s.top() != '(') return false;
                s.pop();
            }
        }
        return s.empty();
    }

    std::string Trans() {
        std::stack<char> opStack;
        std::ostringstream output;
        for (char ch : infix) {
            if (isdigit(ch)) { 
                output << ch; // 添加数字
            } 
            else if (ch == ' ') {  
                continue; // 跳过空格
            } 
            else { 
                output << ' '; // 在每个数字和运算符之间加空格
                if (ch == '(') {
                    opStack.push(ch);
                }
                else if (ch == ')') {
                    while (!opStack.empty() && opStack.top() != '(') {
                        output << opStack.top(); // 输出栈顶元素
                        output << ' ';  // 添加空格分隔
                        opStack.pop();
                    }
                    opStack.pop(); // 弹出左括号
                } 
                else {  
                    while (!opStack.empty() && precedence(opStack.top()) >= precedence(ch)) {
                        output << opStack.top(); // 输出栈顶元素
                        output << ' ';  // 添加空格分隔
                        opStack.pop();
                    }
                    opStack.push(ch); // 当前运算符入栈
                }
            }
        }

        while (!opStack.empty()) { 
            output << opStack.top(); // 输出栈顶元素
            output << ' ';  // 添加空格分隔
            opStack.pop();
        }

        return output.str();
    }

    int GetValue(const std::string& postfixExp) {
        std::stack<int> valueStack;
        std::istringstream iss(postfixExp);
        std::string token;

        while (iss >> token) {
            if (isdigit(token[0])) {
                valueStack.push(std::stoi(token));
            } 
            else {                
                int b = valueStack.top(); valueStack.pop();
                int a = valueStack.top(); valueStack.pop();

                switch (token[0]) {
                    case '+': valueStack.push(a + b); break;
                    case '-': valueStack.push(a - b); break;
                    case '*': valueStack.push(a * b); break;
                    case '/':
                        if (b != 0)
                            valueStack.push(a / b);
                        else
                            throw std::runtime_error("Division by zero");
                        break;
                 }
             }
         }

         return valueStack.top();
     }


private:
    int precedence(char op) const {
        switch (op) {
          case '+':
          case '-':
              return 1;
          case '*':
          case '/':
              return 2;
          default:
              return 0;  
         }
     }
};

int main() {
    std::string input;

    Express expr(""); 

    std::cout << "请输入中缀表达式: ";
    while (true) {
        getline(std::cin, input);
        expr = Express(input);

       if (expr.isMatch()) {
           std::cout << "中缀表达式中括号正确: " << input << '\n';
           break;
       } 
       else {            
           std::cout << "中缀表达式中输入的括号不对,请重新输入:";
       }
   }

   auto postfixExp = expr.Trans();
   std::cout << "后缀表达式:" << postfixExp.substr(1) << '\n';  
   try {     
       int result = expr.GetValue(postfixExp);
       std::cout << "求值结果:" << result << '\n';  
   }   
   catch (const std::exception& e) {         
       std::cerr << e.what() << '\n';    
   }  

   return 0;     
}

主要改动如下:

  • Trans() 方法中,每次添加数字或操作符到输出字符串之前添加了一个空格。这确保了在获取后缀表达式时,数字和操作符之间都有明确的分隔。
  • 调整了相应地方确保无论是计算还是返回结果都能按照预期工作。

现在你可以尝试用不同形式的有效输入来测试该程序,包括带有或不带有括号的情况。


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=20564

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?