在你的代码中,当输入的中缀表达式没有括号(如 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助手提供,问题来源于学员提问