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

时间:2015-03-04 22:41:29

标签: c++ linked-list postfix-notation

我有一项任务,我需要创建一个后缀计算器。我遇到了一些困难,以前有关SO主题的问题没有充分涵盖。

以下是我想要处理的输入示例:

12 6 +

2 *

[回程]

结果:36

作业说明:

  

我们通常使用的算术表达式是中缀表达式,这意味着运算符出现在两个操作数之间,如“4 + 5”。在后缀表达式中,运算符出现在其操作数之后,如“4 5 +”。这是一个稍微复杂的后缀表达式:“25 12 7 - 2 * /”。等价的中缀表达式是:“25 /((12-7)* 2)”。该表达式的结果应为2.5(不要使用整数除法)。后缀表达式不需要括号。

     

编写一个使用堆栈来评估后缀表达式的程序。   每个输入表达式应该在它自己的行上输入,并且   程序应在用户输入空行时终止。唯一的   表达式中的符号将是+, - ,*,/,数字和空格。

     

提示:从左到右阅读后缀表达式。当你读一个   数字,把它推到堆栈上。当您读取操作数时,弹出顶部   堆栈中的两个数字,将操作符应用于它们,然后按下   结果在堆栈顶部。最后,表达的结果   应该是堆栈中唯一的数字。

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

#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.

我在哪里挣扎:

  • 我的while循环应该允许每个规范输入多行。我最初使用的是cin而不是getline,但这就产生了相反的问题:无限制的行输入任何东西,即使检查/ r和空字符串也是如此。

  • 我正试图跳过循环中的空格,但我的条件似乎跳过了任何不是空格的东西。

  • 检查字符串下标意味着我只能使用一位数字,这绝对不是我想要的。当我遇到一个数字:我想我可以检查下一个元素,如果那是一个数字,那么我可以连接它们并提高循环计数器。从理论上讲,至少。在我开始工作之前,我想获得基本的功能。

1 个答案:

答案 0 :(得分:2)

  

我的while循环应该允许每个规范输入多行。

您已找到getline。你可以简单地用它来读取整行。你采取的方法看起来很好。

  

我试图跳过循环中的空格,但我的条件似乎跳过了任何不是空格的东西。

那是对的。您正在检查string::compare的结果,但结果不是布尔值,而非零并不意味着字符串相等,这意味着它们不是&#39; t 相等。

您执行比较的方式并不常见,BTW,更常见的是将字符与' '进行比较,或使用isspaceisblank

  

检查字符串下标意味着我只能使用一位数字,这绝对不是我想要的。

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

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