使用堆栈C++后缀表达式

C++ Postfix Expressions Using Stacks

本文关键字:后缀 表达式 C++ 堆栈      更新时间:2023-10-16

我正在开发一个程序,用于计算我的一门计算机科学课程的后缀表达式的结果。该程序使用堆栈 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;
    }
}

一个问题是,在语句s.pop() - s.pop()(以及类似的除法)中,不能保证哪个s.pop()首先被调用。 因此,从堆栈中删除内容的顺序并不一致。 您应该将其作为两个单独的调用来执行。

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

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

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

首先更改:

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

自:

while (getline(infile, input))

看看它是否效果更好。

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

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

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