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
how to print out all elements in a std::stack or std::queue conveniently
提问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::stack
and std::queue
just like any other supported type!
您可以流式传输std::stack
,std::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
- If you need to do this, then stack or queue is not the correct choice of container.
- 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.
- 如果您需要这样做,那么堆栈或队列不是容器的正确选择。
- 如果您仍然坚持这样做,最好的方法是制作副本并从中弹出元素并打印它们。我不会建议另一种方式,因为没有意义。
回答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。