在 C++ 中创建一个后缀计算器?

Creating a postfix calculator in C++?

我有一个作业需要创建一个后缀计算器。我 运行 遇到了一些困难,之前关于 SO 主题的问题没有充分涵盖。

这是我要处理的输入示例:

12 6 +

2 *

[马车return]

结果:36

作业说明:

The arithmetical expressions we normally use are infix expressions, meaning that the operator appears between its two operands, as in "4 + 5". In postfix expressions, the operator appears after its operands, as in "4 5 +". Here is a slightly more complex postfix expression: "25 12 7 - 2 * /". The equivalent infix expression is: "25 / ((12 - 7) * 2)". The result of that expression should be 2.5 (don't use integer division). Postfix expressions don't require parentheses.

Write a program that uses a stack to evaluate postfix expressions. Each input expression should be entered on its own line, and the program should terminate when the user enters a blank line. The only symbols in an expression will be +, -, *, /, digits and spaces.

Hint: Read a postfix expression from left to right. When you read a number, push it on the stack. When you read an operand, pop the top two numbers off the stack, apply the operator to them, and push the result on top of the stack. At the end, the result of the expression should be the only number on the stack.

到目前为止,这是我的代码:

#include <list> /* Linked Lists */
#include <stack> /* Stacks */
#include <iostream> /* cout cin */


int main() {

    std::stack< double, std::list<double> > postfixStack;
    std::string input;

    std::cout << "Enter a postfix expression: ";

    std::getline(std::cin, input);

    while (input != "") {
        std::cout << "Input expression: " << input << std::endl;
        for (int i = 0; i<input.length()-1; i++) {
            if (input.compare(i, 1, " ")) { // should ignore spaces, but doesn't
                std::cout << "Skipping element " << i << " \n";
            } else if (static_cast<int>(input[i]) == input[i]) { // push numbers onto the stack
                postfixStack.push(static_cast<double>(input[i]));
                std::cout << "Pushing " << input[i] << " onto the stack.\n";
            } else if (input.compare(i, 1, "+")) { // pop two numbers off the stack (1), apply the operator to them (2), and push that onto the stack (3)
                double operand1 = postfixStack.top();
                postfixStack.pop();
                double operand2 = postfixStack.top();
                postfixStack.pop();
                postfixStack.push(operand1 + operand2);
                std::cout << "Adding " << operand1 << " and " << operand2 << std::endl;
            }
        }
        std::getline(std::cin, input);
    }

    if (!postfixStack.empty()) {
        std::cout << "Result of expression: " << postfixStack.top() << std::endl;
    } else {
        std::cout << "It appears that you did not enter an expression to evaluate.\n";
    }

    return 0;
}

Syntax highlighting and line numbers on Gist.

我挣扎的地方:

My while loop should allow more than one line of input per the spec.

您已经找到 getline。您可以简单地使用它来阅读整行。您采用的方法看起来不错。

I'm trying to skip over spaces in my loop, but instead my conditional appears to skip over anything that isn't a space.

没错。您正在检查 string::compare 的结果,但结果不是布尔值,非零并不意味着字符串相等,这意味着它们 不是 等于。

你执行比较的方式并不常见,顺便说一句,更常见的是简单地将字符与 ' ' 进行比较,或者使用 isspace or maybe isblank.

Checking string subscripts means that I can only use numbers with one digit, which definitely isn't what I want.

没错。当您看到一个数字时,您可以进入一个嵌套循环来读取所有后续数字。基本情况,一个一位数字的字符串,被简单地转换为一个数字。 (但只是比您想象的要简单一点,请参阅下面的注释。)如果您知道如何确定 N 位字符串的值(比方说 ABC),则可以确定 N 的值+1 位字符串(假设 ABCD)乘以 10,然后加上下一位的值。

注意:static_cast<int>(input[i]) == input[i] 始终为真。这并不意味着你认为的意思。使用您的调试器检查某些字符的 static_cast<int>(input[i]) 的值,并尝试了解此转换在做什么。当你理解了它的作用后,想想你可以做的另一项检查,以及你如何使用它,在检查一个字符是一个数字后,确定该数字的数值。