Я делаю постфиксный калькулятор и хочу добавить в него новую функцию. Как я могу суммировать все элементы в стеке, а затем удалить элементы, используемые для суммирования, из стека, а затем вернуть сумму обратно в стек? Все это должно происходить по нажатию команды 's'.

Я пытался сделать это так, но он всегда печатает только 0.

    case 's':
        if (numbers.top().first == underflow)
            cout << "Stack empty" << endl;
        else {
            numbers.pop();
            if (numbers.top().first == underflow) {
                cout << "Stack has just one entry" << endl;
                numbers.push(p);
            }

            else {
                while (!numbers.empty()) {
                    sum += numbers.top().second;

                }
                numbers.push(sum);
                cout << sum << endl;

            }
        }
        break;

Вот некоторый код моего main.cpp.

#include <iostream>
#include "Stack.h"
#include <cmath>
using namespace std;

void help()
{
    cout
        << "[?]push to stack [=]print top [x]exchange [s]sum [a]average" << endl
        << "[+] [-] [*] [/] [%] [^] [v] are arithmetic operations" << endl
        << "[Q]uit." << endl;
}

char get_command()
{
    char command;
    bool waiting = true;
    cout 
        << "Select command and press <Enter>:" << endl;

    while (waiting) {
        cin >> command;
        command = tolower(command);
        if (command == '?' || command == '=' || command == '+' ||
            command == '-' || command == '*' || command == '/' ||
            command == 'q' || command == 'x' || command == 's' || 
            command == 'a' || command == '%' || command == '^' || 
            command == 'v') waiting = false;


        else {
            cout << "Please enter a valid command:" << endl;
        }
    }
    return command;
}


bool do_command(char command, Stack& numbers)

{
    double p, q, g, r;
    double sum = 0;
    switch (command) {
    case '?':
        cout << "Enter a real number: " << flush;
        cin >> p;
        if (numbers.push(p) == overflow)
            cout << "Warning: Stack full, lost number" << endl;
        break;

    case '=':
        if (numbers.top().first == underflow)
            cout << "Stack empty" << endl;
        else
            cout << p << endl;
        break;

    case '+':
        if (numbers.top().first == underflow)
            cout << "Stack empty" << endl;
        else {
            numbers.pop();
            if (numbers.top().first == underflow) {
                cout << "Stack has just one entry" << endl;
                numbers.push(p);
            }

            else {
                numbers.pop();
                if (numbers.push(q + p) == overflow)
                    cout << "Warning: Stack full, lost result" << endl;
            }
        }
        break;

    case '-':
        if (numbers.top().first == underflow)
            cout << "Stack empty" << endl;
        else {
            numbers.pop();
            if (numbers.top().first == underflow) {
                cout << "Stack has just one entry" << endl;
                numbers.push(p);
            }

            else {
                numbers.pop();
                if (numbers.push(q - p) == overflow)
                    cout << "Warning: Stack full, lost result" << endl;
            }
        }
        break;

    case '*':
        if (numbers.top().first == underflow)
            cout << "Stack empty" << endl;
        else {
            numbers.pop();
            if (numbers.top().first == underflow) {
                cout << "Stack has just one entry" << endl;
                numbers.push(p);
            }

            else {
                numbers.pop();
                if (numbers.push(q * p) == overflow)
                    cout << "Warning: Stack full, lost result" << endl;
            }
        }
        break;

    case '/':
        if (numbers.top().first == underflow)
            cout << "Stack empty" << endl;
        else {
            numbers.pop();
            if (numbers.top().first == underflow) {
                cout << "Stack has just one entry" << endl;
                numbers.push(p);
            }

            else {
                numbers.pop();
                if (numbers.push(q / p) == overflow)
                    cout << "Warning: Stack full, lost result" << endl;
            }
        }
        break;

    case 'x':
        if (numbers.top().first == underflow)
            cout << "Stack empty" << endl;
        else {
            numbers.pop();
            if (numbers.top().first == underflow) {
                cout << "Stack has just one entry" << endl;
                numbers.push(p);
            }

            else {
                numbers.pop();
                numbers.pop();
                numbers.push(p);
                numbers.push(q);
            }
        }
        break;

    case 's':
        if (numbers.top().first == underflow)
            cout << "Stack empty" << endl;
        else {
            numbers.pop();
            if (numbers.top().first == underflow) {
                cout << "Stack has just one entry" << endl;
                numbers.push(p);
            }

            else {
                while (!numbers.empty()) {
                    sum += numbers.top().second;

                }
                numbers.push(sum);
                cout << sum << endl;

            }
        }
        break;

Вот мой Stack.cpp.

Error_code Stack::push(const Stack_entry& item)
/*
Pre:  None.
Post: If the Stack is not full, item is added to the top
      of the Stack.  If the Stack is full,
      an Error_code of overflow is returned and the Stack is left unchanged.
*/

{
    Error_code outcome = success;
    if (count >= maxstack)
        outcome = overflow;
    else
        entry[count++] = item;
    return outcome;
}


Error_code Stack::pop()
/*
Pre:  None.
Post: If the Stack is not empty, the top of
      the Stack is removed.  If the Stack
      is empty, an Error_code of underflow is returned.
*/

{
    Error_code outcome = success;
    if (count == 0)
        outcome = underflow;
    else --count;
    return outcome;
}


pair<Error_code, int> Stack::top() const
{
    pair<Error_code, int> p;
    Error_code outcome = success;
    if (count == 0) 
        p.first = underflow;
        p.second = 0;
        return p;

    p.first = outcome;
    p.second = entry[count - 1];
    return p;
}

Вот мой Stack.h

#include "Utility.h"

typedef double Stack_entry;

const int maxstack = 10;

class Stack {
public:
    Stack();
    bool empty() const;
    Error_code pop();
    //Error_code top(Stack_entry& item) const;
    Error_code push(const Stack_entry& item);
    //Error_code pop_top(Stack& s, Stack_entry& item);
    double size() const; 
    std::pair<Error_code, int> top() const;

private:
    int count;
    Stack_entry entry[maxstack];
};

Я ожидаю, что он суммирует все числа в стеке, а затем удалит их, а затем вернет в стек. Буду очень признателен за любую помощь. Заранее спасибо.

1
MoskiMeruna 27 Окт 2019 в 15:23

1 ответ

pop не возвращает значение, как другие языки C++. Вам нужно использовать функцию top для возврата верхнего элемента в стеке. Вы можете добавить этот элемент в сумму, а затем удалить его с помощью pop. Вы можете реализовать это, как показано ниже:

while (!numbers.empty()) 
{
    sum += numbers.top();
    numbers.pop()
}

Для другого запроса Op:

Измените реализацию top на это:

std::pair<Error_code,int> top() const
    {
        std::pair<Error_code,int> p;
        Error_code outcome = success;
        if (count == 0)
            p.first = underflow;
            p.second = 0;
            return p;

        p.first = outcome;
        p.second = entry[count -1];
        return p;
    }

И решение вашей первой проблемы становится таким:

while (!numbers.empty()) 
    {
        sum += numbers.top().second;
        numbers.pop()
    }

Если вы хотите outcome, вы можете сделать numbers.top().first. Это все.

2
Mert Köklü 27 Окт 2019 в 20:27
Спасибо, но проблема в том, что для функции top() требуется параметр, и независимо от того, что я туда добавляю, я просто получаю 0. @Marceline
 – 
MoskiMeruna
27 Окт 2019 в 18:46
Но почему для этого требуется параметр? Если это так, функция top становится бессмысленной.
 – 
Mert Köklü
27 Окт 2019 в 19:00
Это наша домашняя работа, и идея состоит в том, чтобы использовать уже созданные функции. Видите ли вы какой-либо другой способ сделать это? @Марселин
 – 
MoskiMeruna
27 Окт 2019 в 19:07
Как видите, вы ничего не можете сделать, чтобы получить элемент из этой реализации стека, потому что операции этой реализации стека возвращают только Error_code, а не значение. Вы можете изменить тип возвращаемого значения top на пару (чтобы вы могли возвращать как результат, так и значение. Если реализацию запрещено изменять, вы ничего не можете сделать. Если это не запрещено, сообщите мне. Я отредактирует мой ответ.
 – 
Mert Köklü
27 Окт 2019 в 19:57
Хорошо, большое спасибо за помощь. Я думаю, что редактирование функций не запрещено, поэтому вы можете изменить его, если хотите. @Марселин
 – 
MoskiMeruna
27 Окт 2019 в 20:05