📜  从预购和中序计算器发布订单 - C++ (1)

📅  最后修改于: 2023-12-03 15:22:03.029000             🧑  作者: Mango

从预购和中序计算器发布订单 - C++
简介

这是一个用C++实现的计算器程序,支持预购和中序计算。 它基本上可以执行所有标准算术运算,还提供了一些其他功能,如幂运算和平方根。 此外,该程序还能够处理括号,以及支持变量和自定义的函数。

实现

从预购表达式计算

从预购表达式计算非常简单,因为没有括号,运算符的优先级是一样的。 实现的步骤如下:

  1. 从左到右遍历表达式
  2. 如果是数字,那么将其推入栈中
  3. 如果是运算符,则从栈中弹出两个数字执行算术运算,把结果推回栈中
  4. 重复步骤1到3,直到遍历完整个表达式
  5. 最后弹出栈中唯一一个元素就是答案
double evaluatePrefix(string expression) {
    stack<double> numbers;

    for (int i = expression.size() - 1; i >= 0; i--) {
        if (isdigit(expression[i])) {
            int j = i;
            while (i >= 0 && isdigit(expression[i])) i--;
            double num = stod(expression.substr(i + 1, j - i));
            numbers.push(num);
        } else {
            double num1 = numbers.top();
            numbers.pop();
            double num2 = numbers.top();
            numbers.pop();

            switch (expression[i])
            {
            case '+': numbers.push(num1 + num2); break;
            case '-': numbers.push(num1 - num2); break;
            case '*': numbers.push(num1 * num2); break;
            case '/': numbers.push(num1 / num2); break;
            case '^': numbers.push(pow(num1, num2)); break;
            }
        }
    }

    return numbers.top();
}

从中序表达式计算

从中序表达式计算比较困难,因为我们需要知道每个运算符的优先级和结合性,以及要处理括号。 为了处理这个问题,我们可以使用两个栈,一个用于运算符,一个用于操作数。 实现的步骤如下:

  1. 从左到右遍历表达式
  2. 如果是数字,那么将其推入操作数栈中
  3. 如果是左括号,那么将其推入运算符栈中
  4. 如果是右括号,那么从运算符栈中弹出运算符和操作数,执行运算,把结果推回操作数栈中,直到找到左括号
  5. 如果是运算符,那么把所有优先级大于等于它的运算符弹出栈,执行运算,把结果推回操作数栈中
  6. 重复步骤1到5,直到遍历完整个表达式
  7. 最后操作数栈中唯一一个元素就是答案
int getPrecedence(char op) {
    if (op == '*' || op == '/') return 2;
    if (op == '+' || op == '-') return 1;
    return 0;
}

double evaluateInfix(string expression) {
    stack<char> operators;
    stack<double> numbers;

    for (int i = 0; i < expression.length(); i++) {
        if (isspace(expression[i])) {
            continue;
        } else if (isdigit(expression[i])) {
            int j = i;
            while (i < expression.length() && isdigit(expression[i])) i++;
            double num = stod(expression.substr(j, i - j));
            numbers.push(num);
            i--;
        } else if (expression[i] == '(') {
            operators.push(expression[i]);
        } else if (expression[i] == ')') {
            while (operators.top() != '(') {
                double num2 = numbers.top();
                numbers.pop();
                double num1 = numbers.top();
                numbers.pop();
                char op = operators.top();
                operators.pop();
                double result = applyOperator(op, num1, num2);
                numbers.push(result);
            }
            operators.pop();
        } else {
            while (!operators.empty() && getPrecedence(operators.top()) >= getPrecedence(expression[i])) {
                double num2 = numbers.top();
                numbers.pop();
                double num1 = numbers.top();
                numbers.pop();
                char op = operators.top();
                operators.pop();
                double result = applyOperator(op, num1, num2);
                numbers.push(result);
            }
            operators.push(expression[i]);
        }
    }

    while (!operators.empty()) {
        double num2 = numbers.top();
        numbers.pop();
        double num1 = numbers.top();
        numbers.pop();
        char op = operators.top();
        operators.pop();
        double result = applyOperator(op, num1, num2);
        numbers.push(result);
    }

    return numbers.top();
}
用法

要使用该程序,您只需要从控制台输入表达式,然后它会计算表达式并返回结果。

string expression = "2 + 3 * 4";
double result = evaluateInfix(expression);
cout << result << endl;

此外,您还可以使用自定义的函数和变量,例如:

map<string, double> variables;
variables["x"] = 1.0;
variables["y"] = 2.0;

map<string, function<double(double)>> functions;
function<double(double)> square = [](double x) { return x * x; };
functions["square"] = square;

string expression = "x + y + square(x + y)";
double result = evaluateInfix(expression, variables, functions);
cout << result << endl; // 输出 10
结论

这是一个非常强大的计算器程序,支持各种不同的功能和用法。 虽然它的实现比较复杂,但是它可以帮助您更好地理解算术运算和计算机科学。