Реализация стека с использованием векторов в C ++ - PullRequest
0 голосов
/ 28 сентября 2018
#include<iostream>
#include<vector>
using namespace std;
class Stack {

private:
    int maxSize;
    vector<int> v;
    int top;
public:
    Stack(int size) {
        this->maxSize = size;
        this->v.reserve(this->maxSize);
        this->top = -1;
    }

    void push(int j) {
        if (!(this->isFull())) {
            this->v[++this->top] = j;
        } else {
            cout << "stack is full"<<endl;
        }

    }

    int pop() {
        if (!(this->isEmpty())) {

            return this->v[this->top--];
        } else {
            cout << "\nstack is empty"<<endl;
            cout<<  "StackOverflow "<<endl;
        }
    }

    int peak() {
        return this->v[this->top];
    }
    bool isEmpty() {
        return (this->top == -1);
    }

    bool isFull() {
        return (this->top == this->maxSize - 1);
    }

};

int main() {

    Stack s(10);

    s.push(10);
    s.push(20);
    cout<<s.pop();
    cout<<"\n"<<s.pop();
    s.push(40);
    cout<<"\n"<<s.pop();

}

Как я могу сделать этот код более качественным и надежным по следующим причинам:

  • Вывод этого кода составляет 20 10 40.

  • Но в выводе я хочу напечатать «Стек пуст» после каждого раза, когда стек пуст, после выталкивания всех элементов из стека

  • Не удается распечатать "Stackis Empty" каждый раз.

Ответы [ 3 ]

0 голосов
/ 28 сентября 2018

У вас в коде UB:

this->v[++this->top] = j;

 return this->v[this->top--];    

и так далее.Тот факт, что вы зарезервировали пространство в std::vector, не делает доступ к этим элементам легальным, вы получаете доступ к элементам за пределами.И вы слишком усложнили свой код - std::vector поддерживает его размер, поэтому вам вообще не нужен индекс top.Все, что вам нужно - это push_back() добавить элемент и использовать back() для доступа к последнему, а затем pop_back() для его удаления.Вы можете использовать std::vector>::empty() или std::vector::size(), чтобы проверить, остались ли элементы.

0 голосов
/ 28 сентября 2018

Как вы его запрограммировали, он печатает «Стек пуст», только если стек уже пуст при вызове pop, а не когда он имеет 1 элемент и пуст только после вызова pop.

Предположим, у вас есть 1 элемент в стеке.Таким образом, top равно 0.

int pop() {
    if (!(this->isEmpty())) {

Это if оценивается как true, и поэтому ничего не будет напечатано.Это потому, что isEmpty() оценивается в false с top, установленным в 0.

В первую очередь вам нужно сделать pop, а , а затем , проверить, пуст ли стек,В любом случае нужно проверить это в начале, потому что вы не можете выбросить пустой стек.

0 голосов
/ 28 сентября 2018

Конкретная проблема в вашем коде связана с попыткой выхода за пределы границы с помощью std::vector;поведение которого undefined .Обратите внимание, что reserve не делает такое количество элементов доступным для использования;только потенциально доступно без последующего перераспределения памяти.Если бы вы использовали at вместо [], то ваша стандартная библиотека C ++ вызвала бы ошибку времени выполнения.

std::vector имеет push_back и функции pop_back, которые позволяют вам использовать ееразумно эффективно смоделировать стек.

Но , typedef std::stack<int> Stack; вместо всего вашего кода, безусловно, лучший способ.

Не используйте стандартную библиотеку C ++объекты-контейнеры для моделирования других контейнеров, которые также находятся в стандартной библиотеке C ++.Контейнерные объекты действительно трудно писать правильно;и много отлаживать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...