簡體   English   中英

如何在C ++中顯示(或遍歷)堆棧

[英]How to display (or loop through) a stack in c++

我是c ++的新手,正在嘗試弄清楚通過程序運行后如何顯示堆棧的內容。

int main(){
  int userInput;
  Stack st1,st2;
  cin>>userInput;
  int i,topStack;
  while(userInput!=-9){
    while(userInput>0){
      st1.push(userInput);
      topStack=st1.pop()
      st2.push(topStack);
  }
    if(userInput<0){
      for(i=0;i<(-userInput);++i){
        st2.pop();
      }
    }
  }
}

輸入值后,我想看看st2是什么樣子。 不太確定如何執行此操作和/或是否可行。 資源將不勝感激!

這是自定義類定義:

class ListNode{
  public:
    int content;
    ListNode* pNext;
};
class Stack{
  private:
    ListNode* top;
  public:
    Stack();
    ~Stack();
    int pop();
    void push(int);
};
Stack::Stack(){
  top=nullptr;
}
void Stack::push(int x){
  ListNode *newNode;
  newNode=new ListNode;
  newNode->content=x;
  newNode->pNext=top;
  top=newNode;
}
int Stack::pop(){
  int fR=-17; //empty stack
  if(top!=nullptr){
    ListNode* newNode;
    newNode=top;
    top=top->pNext;
    fR=newNode->content;
    delete newNode;
  }
  return fR;
}
Stack::~Stack(){
  while(top!=nullptr){
    pop();
  }
}

這是迭代器類的一個相當最小的實現,以允許查看Stack對象的內容。

我還對現有代碼進行了一些更改,以使其更符合現代C ++最佳實踐。 特別是,您幾乎不應該使用raw new並直接delete ,因此我更新了代碼以使用std::unique_ptr

stack_iterator.hpp:

#include <iterator>
#include <memory>

#pragma once

class Stack {
private:
    struct ListNode {
        int content;
        std::unique_ptr<ListNode> pNext;
    };

public:
    Stack() = default;
    Stack(const Stack&) = delete;
    Stack(Stack&&) = delete;
    Stack& operator=(const Stack&) = delete;
    Stack& operator=(Stack&&) = delete;

    void push(int);
    int pop();

    class const_iterator {
    public:
        using difference_type = std::ptrdiff_t;
        using value_type = const int;
        using pointer = const int*;
        using reference = const int&;
        using iterator_category = std::forward_iterator_tag;

        const_iterator() = delete;
        const_iterator(const const_iterator&) = default;
        const_iterator& operator=(const const_iterator&) = default;

        // Constructor making a const_iterator pointing to a particular
        // list node.
        const_iterator(ListNode*);

        // Pre-increment operator, e.g. called by ++i
        const_iterator& operator++();

        // Post-increment operator, e.g. called by i++
        const_iterator operator++(int);

        // Deference operator, e.g. called by *i
        reference operator*() const;

        // Comparison operators
        bool operator==(const const_iterator&) const;
        bool operator!=(const const_iterator&) const;

    private:
        ListNode* pNode;

        friend class Stack;
    };

    // Accessors to create iterators to start and end of stack.
    // Note that the stack is traversed from most recent to least
    // recent entries.  Also note that a pop() operation will invalidate
    // any iterator referring to the most recent entry of the stack.
    const_iterator begin() const;
    const_iterator end() const;

private:
    std::unique_ptr<ListNode> top;
};

stack_iterator.cpp:

#include "stack_iterator.hpp"

void Stack::push(int x) {
    auto newNode = std::make_unique<ListNode>();
    newNode->content = x;
    newNode->pNext = std::move(top);
    top = std::move(newNode);
}

int Stack::pop() {
    static constexpr int retvalOnEmpty = -17;

    auto oldTop = std::move(top);
    if (oldTop != nullptr) {
        top = std::move(oldTop->pNext);
        return oldTop->content;
    }
    return retvalOnEmpty;
}

// pre-increment operator
Stack::const_iterator& Stack::const_iterator::operator++() {
    pNode = pNode->pNext.get();
    return *this;
}

// post-increment operator
Stack::const_iterator Stack::const_iterator::operator++(int) {
    auto ret_iterator = *this;
    ++(*this);
    return ret_iterator;
}

// dereference operator
Stack::const_iterator::reference Stack::const_iterator::operator*() const {
    return pNode->content;
}

// comparison operators
bool Stack::const_iterator::operator==(const Stack::const_iterator& other) const {
    return this->pNode == other.pNode;
}

bool Stack::const_iterator::operator!=(const Stack::const_iterator& other) const {
    return this->pNode != other.pNode;
}

// semi-private constructor making an iterator pointing to a particular ListNode
Stack::const_iterator::const_iterator(ListNode* i_node) :
    pNode(i_node)
{ }

Stack::const_iterator Stack::begin() const {
    return Stack::const_iterator{top.get()};
}

Stack::const_iterator Stack::end() const {
    return Stack::const_iterator{nullptr};
}

主程序示例顯示了如何使用迭代器:

#include "stack_iterator.hpp"
#include <iostream>
#include <algorithm>

int main() {
    Stack s;
    s.push(3);
    s.push(5);
    s.push(-4);

    std::cout << "Contents of stack: ";
    for (auto n : s)
        std::cout << n << ' ';
    std::cout << '\n';

    // Alternative
    std::cout << "Contents of stack, using ostream_iterator: ";
    std::copy(s.begin(), s.end(), std::ostream_iterator<int>{std::cout, " "});
    std::cout << '\n';

    return 0;
}

使用標准庫的容器的兩種方法:

  1. 完全放棄自己的堆棧實現,並使用標准庫中提供的一個實現: std::stack 要顯示元素,請執行以下操作:

     void print(std::ostream& os, std::stack s, char delimiter = ' ') { if (not s.empty()) { std::cout << s.top(); } while (not s.empty()) { std::cout << delimiter << s.top(); } } 

    由於您要按傳遞堆棧,因此您實際上是在復制它。

  2. 使用您自己的堆棧實現,但是在std::list實現它,並公開列表的迭代器(類似於Daniel Schepler的回答,但沒有很多艱苦的工作...)。

當然,最好先實現一個operator<<然后再實現一個打印函數,但是原理是相同的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM