C++ 如何方便地打印出 std::stack 或 std::queue 中的所有元素

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4523178/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 15:38:40  来源:igfitidea点击:

how to print out all elements in a std::stack or std::queue conveniently

c++

提问by Qiang Li

If I do not to want to create a new container in order to do so?

如果我不想创建一个新的容器来这样做?

回答by AraK

I've written a snippet to do that for debugging. For example:

我写了一个片段来做调试。例如:

std::stack<int> s; // works with std::queue also!
s.push(1);
s.push(2);

std::cout << s; // [ 1, 2 ]

Please forgive me for this hackish code! but this is what I've written months ago:

请原谅我这个黑客代码!但这是我几个月前写的:

#include <stack>
#include <queue>
#include <ostream>

template <class Container, class Stream>
Stream& printOneValueContainer
    (Stream& outputstream, const Container& container)
{
    typename Container::const_iterator beg = container.begin();

    outputstream << "[";

    while(beg != container.end())
    {
        outputstream << " " << *beg++;
    }

    outputstream << " ]";

    return outputstream;
}

template < class Type, class Container >
const Container& container
    (const std::stack<Type, Container>& stack)
{
    struct HackedStack : private std::stack<Type, Container>
    {
        static const Container& container
            (const std::stack<Type, Container>& stack)
        {
            return stack.*&HackedStack::c;
        }
    };

    return HackedStack::container(stack);
}

template < class Type, class Container >
const Container& container
    (const std::queue<Type, Container>& queue)
{
    struct HackedQueue : private std::queue<Type, Container>
    {
        static const Container& container
            (const std::queue<Type, Container>& queue)
        {
            return queue.*&HackedQueue::c;
        }
    };

    return HackedQueue::container(queue);
}

template
    < class Type
    , template <class Type, class Container = std::deque<Type> > class Adapter
    , class Stream
    >
Stream& operator<<
    (Stream& outputstream, const Adapter<Type>& adapter)
{
    return printOneValueContainer(outputstream, container(adapter));
}

You can stream std::stackand std::queuejust like any other supported type!

您可以流式传输std::stackstd::queue就像任何其他受支持的类型一样!

回答by Etienne de Martel

You can't iterate through a stack or a queue. In fact, SGI's documentation says this (it's about stack, but it's the same reason for queue):

您不能遍历堆栈或队列。事实上,SGI 的文档是这样说的(它是关于堆栈的,但它与队列的原因相同):

This restriction is the only reason for stack to exist at all. Note that any Front Insertion Sequence or Back Insertion Sequence can be used as a stack; in the case of vector, for example, the stack operations are the member functions back, push_back, and pop_back. The only reason to use the container adaptor stack instead is to make it clear that you are performing only stack operations, and no other operations.

这个限制是堆栈存在的唯一原因。请注意,任何前插入序列或后插入序列都可以用作堆栈;以vector为例,栈操作是成员函数back、push_back、pop_back。使用容器适配器堆栈的唯一原因是要明确说明您只执行堆栈操作,而不执行其他操作。

So, if you really want to do this, you'll have to empty the stack (or queue):

所以,如果你真的想这样做,你必须清空堆栈(或队列):

std::stack<Whatever> s;
// ...
while(!s.empty())
{
    Whatever w = s.top();
    std::cout << w;
    s.pop();
}

回答by Benjamin Lindley

  1. If you need to do this, then stack or queue is not the correct choice of container.
  2. If you still insist on doing this, the best way is to make a copy and pop elements off of it and print them. I'm not going to suggest another way because there's no point.
  1. 如果您需要这样做,那么堆栈或队列不是容器的正确选择。
  2. 如果您仍然坚持这样做,最好的方法是制作副本并从中弹出元素并打印它们。我不会建议另一种方式,因为没有意义。

回答by Sam

ostream & operator<<(ostream & os, stack<double> my_stack) //function header
{
    while(!my_stack.empty()) //body
    {
        os << my_stack.top() << " ";
        my_stack.pop();
    }
    return os; // end of function
}


/*
using this simple overloaded operator function, you're able to print out all the components of a stack by doing a simple cout << your_stack_name;*/

回答by Tariq Ayman

It can be easily done using recursion you just need to know when to re-addthe next element

使用递归可以轻松完成,您只需要知道何时重新添加下一个元素

For Stack

对于堆栈

void print(stack<char> &s)
{
    if(s.empty())
    {
        cout << endl;
        return;
    }
    char x= s.top();
    s.pop();
    print(s);
    s.push(x);
    cout << x << " ";
 }

And this one is For Queue

而这个是For Queue

void print(queue<char> &s,int num)
{
    if(!num)
    {
        cout << endl;
        return;
    }
    char x= s.front();
    s.pop();
    cout << x << " ";
    s.push(x);
    print(s,--num);
}

Good Luck

祝你好运

回答by joshbodily

Posting b/c I found this useful for debugging. Pop from original into a temp and then pop from temp back into original:

发布 b/c 我发现这对调试很有用。从原始弹出到临时,然后从临时弹出回到原始:

template <typename T>
void dump_stack(std::stack<T>& stack) {
  std::stack<T> temp;
  while (!stack.empty()) {
    T top = stack.top(); stack.pop();
    std::cout << top << " ";
    temp.push(top);
  }
  while (!temp.empty()) {
    T top = temp.top(); temp.pop();
    stack.push(top);
  }
}

回答by baziorek

I've found solution which should work with all implementations (IMO) of std::stack, but unfortunately the stack must use std::vector instead of queue.

我找到了适用于 std::stack 的所有实现 (IMO) 的解决方案,但不幸的是,堆栈必须使用 std::vector 而不是队列。

template<typename T>
void printStack(const std::stack<T, std::vector<T>>& s)
{
    typedef typename std::stack<T>::const_reference EntryTypeRef;
    typedef std::remove_reference_t<EntryTypeRef> EntryType;

    for(size_t i=0; i < s.size(); ++i)
    {
        EntryType* e = &s.top();
        cout << *(e-i) << endl;
    }
}

std::vector is dynamic array, so we can use pointer arytmetics.

std::vector 是动态数组,所以我们可以使用指针算法。

The marked answer to the question assumes, that the stack has field named 'c', I have another solution which would work with std::stack implementation which has container as first field, but its name does not matter:

该问题的标记答案假设堆栈具有名为“c”的字段,我有另一个解决方案可以与 std::stack 实现一起使用,该实现将容器作为第一个字段,但其名称无关紧要:

template<typename T>
void printStack(const std::stack<T>& s)
{
    typedef typename std::stack<T>::container_type Container;

    const auto containerPtr = reinterpret_cast<const Container*>(&s);

    for(auto e : *containerPtr)
        cout << e << endl;
}

回答by user2376997

Try this:

尝试这个:

template<typename T, typename C>
struct myStack : std::stack<T, C> {
    typedef std::stack<T, C> Stack;
    using Stack::stack;
    using Stack::c;                   
};

int main() 
{
    myStack<int, std::deque<int>> s;
    s.push(1);
    s.push(2);

    std::deque<int>::iterator it = s.c.begin();
    while (it != s.c.end())
        std::cout << ' ' << *it++;
}

Here we expose underlying container of std::stack as member c.

这里我们将 std::stack 的底层容器公开为成员 c。