C++实现算式字符串的输入,输出算式的值

在 C++ 中实现算式字符串的输入和计算功能可以涉及多个步骤,包括解析字符串、处理运算符和运算数,以及计算最终的结果。以下是详细的步骤和示例代码,帮助你实现这一功能:

1. 解析算式字符串

为了计算算式的值,你需要首先解析字符串中的运算符和运算数。一般来说,可以使用两种方法:递归下降解析和 Shunting-yard 算法。这里我们使用 Shunting-yard 算法将表达式转换为后缀表达式,然后计算其值。

2. 实现步骤

2.1 定义运算符优先级

运算符优先级和结合性是计算算式的关键。定义优先级和结合性:

cpp
#include <unordered_map> #include <cctype> #include <string> std::unordered_map<char, int> precedence = { {'+', 1}, {'-', 1}, {'*', 2}, {'/', 2} };

2.2 将中缀表达式转换为后缀表达式

使用 Shunting-yard 算法将中缀表达式转换为后缀表达式:

cpp
#include <stack> #include <vector> #include <sstream> #include <cctype> #include <iostream> // 将中缀表达式转换为后缀表达式 std::vector<std::string> infixToPostfix(const std::string& expression) { std::stack<char> operators; std::vector<std::string> output; std::stringstream number; for (char ch : expression) { if (std::isdigit(ch)) { number << ch; } else { if (!number.str().empty()) { output.push_back(number.str()); number.str(""); } if (ch == '(') { operators.push(ch); } else if (ch == ')') { while (!operators.empty() && operators.top() != '(') { output.push_back(std::string(1, operators.top())); operators.pop(); } operators.pop(); // pop the '(' } else if (precedence.find(ch) != precedence.end()) { while (!operators.empty() && precedence[operators.top()] >= precedence[ch]) { output.push_back(std::string(1, operators.top())); operators.pop(); } operators.push(ch); } } } if (!number.str().empty()) { output.push_back(number.str()); } while (!operators.empty()) { output.push_back(std::string(1, operators.top())); operators.pop(); } return output; }

2.3 计算后缀表达式的值

使用栈来计算后缀表达式的值:

cpp
#include <stack> #include <string> #include <vector> #include <stdexcept> #include <iostream> // 计算后缀表达式的值 double evaluatePostfix(const std::vector<std::string>& postfix) { std::stack<double> values; for (const std::string& token : postfix) { if (std::isdigit(token[0])) { values.push(std::stod(token)); } else { double right = values.top(); values.pop(); double left = values.top(); values.pop(); switch (token[0]) { case '+': values.push(left + right); break; case '-': values.push(left - right); break; case '*': values.push(left * right); break; case '/': if (right == 0) throw std::runtime_error("Division by zero"); values.push(left / right); break; default: throw std::runtime_error("Unknown operator"); } } } return values.top(); }

2.4 主函数示例

将以上部分结合起来,创建一个主函数来处理输入和输出:

cpp
int main() { std::string expression; std::cout << "Enter an expression: "; std::getline(std::cin, expression); // 去除空格 expression.erase(remove(expression.begin(), expression.end(), ' '), expression.end()); try { std::vector<std::string> postfix = infixToPostfix(expression); double result = evaluatePostfix(postfix); std::cout << "Result: " << result << std::endl; } catch (const std::exception& e) { std::cerr << "Error: " << e.what() << std::endl; } return 0; }

总结

  1. 定义运算符优先级:设定不同运算符的优先级和结合性。
  2. 中缀转后缀:使用 Shunting-yard 算法将中缀表达式转换为后缀表达式。
  3. 计算后缀表达式:使用栈计算后缀表达式的值。
  4. 处理输入输出:读取用户输入的算式,进行转换和计算,然后输出结果。

通过以上步骤,你可以实现一个简单的算式计算器,能够处理基本的数学运算。