1

我正在开发一个程序,为我的一门计算机科学课程计算后缀表达式的结果。该程序使用堆栈 ADT 来完成此操作。

我已经编写了程序,但相信可能会有错误,因为某些表达式的结果不正确。我不确定我的错误在哪里。

此外,当输入文件为空时,程序会生成一个值 32767。它来自哪里?

表达式:3 4 + 3 * 值 = 21。

表达式:5 4 3 2 1 - + / * 值 = 0。(应该是 5)

表达式:9 5 2 4 + - 2 * * 值 = 18。(应该是 -18)

头文件:

#ifndef STACK_H
#define STACK_H

#include <cstdlib>
#include <iostream>

class Stack
{
    public:
        typedef int Item;
        static const int CAPACITY = 50;

        // Constructor
        Stack() { used = 0; }

        // Modification Member Functions
        void push(Item entry) {
            data[used] = entry;
            ++used;
        }
        Item pop() {
            if(!empty())
            {
                --used;
                return data[used];
            }
        }

        // Constant Member Functions
        bool empty() const { return used == 0; }
        int size() const { return used; }

    private:
        // Data Members
        Item data[CAPACITY];
        int used;
};
#endif

主程序:

#include <cstdlib>
#include <iostream>
#include <fstream>
#include "stack.h"
using namespace std;

int main()
{
    Stack s;
    string input;
    ifstream infile;
    int final, operand1, operand2, result;
    char infile_name[80];

    cout << "Enter input file name: ";
    cin >> infile_name;
    cout << endl;

    infile.open(infile_name);
    while(!infile)
    {
        cout << "Could not open file." << endl;
        return 0;
    }

    while (!infile.eof())
    {
        getline(infile, input);
        cout << "Expression: ";
        for (int i = 0; i < input.length(); i++)
        {
            cout << input[i];
            if(input[i] == '1' || input[i] == '2' || input[i] == '3' || input[i] == '4' || input[i] == '5' || input[i] == '6' || input[i] == '7' || input[i] == '8' || input[i] == '9')
                s.push(input[i] - '0');
            if(input[i] == '+')
                s.push(s.pop() + s.pop());
            if(input[i] == '-')
                s.push(s.pop() - s.pop());
            if(input[i] == '*')
                s.push(s.pop() * s.pop());
            if(input[i] == '/')
                s.push(s.pop() / s.pop());
        }
        final = s.pop();
        cout << endl << "Value = " << final << "." << endl << endl;
    }
}
4

2 回答 2

3

一个问题是,在语句中s.pop() - s.pop()(在除法中也是如此),不能保证s.pop()首先调用哪个。因此,从堆栈中删除的顺序是不一致的。您应该将其作为两个单独的调用进行。

auto oper1 = s.pop();
auto oper2 = s.pop();
s.push(oper1-oper2);

在您的情况下,您的错误结果是由于这两个操作以错误的顺序执行的。

于 2013-10-15T01:32:38.687 回答
2

类似的代码while (!infile.eof())几乎总是一个错误。它通常会出现两次读取最后一个输入项(尽管即使这样也不可靠)。

从改变开始:

while (!infile.eof())
{
    getline(infile, input);

至:

while (getline(infile, input))

看看它是否效果更好。

另请注意,stack.pop()如果堆栈为空,您不会返回值:

Item pop() {
    if (!empty())
    {
        --used;
        return data[used];
    }
}

如果(例如)您有额外的运算符,您将尝试使用一个实际上没有返回一个值的值,从而导致未定义的行为。

于 2013-10-15T01:31:11.583 回答