在C++中,能否遍历std::stack
?
以下方法不能用于遍历。因为std::stack
没有成员end
。
std::stack<int> foo;
// ..
for (__typeof(foo.begin()) it = foo.begin(); it != foo.end(); it++)
{
// ...
}
在C++中,能否遍历std::stack
?
以下方法不能用于遍历。因为std::stack
没有成员end
。
std::stack<int> foo;
// ..
for (__typeof(foo.begin()) it = foo.begin(); it != foo.end(); it++)
{
// ...
}
在C++中是否可以遍历std::stack?
不行。Stack是一种数据结构,当你想把元素放在栈顶并从栈顶获取元素时应该使用它。如果你需要一个可遍历的Stack,可以考虑使用其他数据结构来模拟栈的行为(例如std::vector
),或者自己编写一个可遍历的Stack。
由于 std::stack
没有 end
成员,因此无法直接遍历它,这就是栈数据结构的设计,即只有一个指针。但是,这里有两个懒惰的方法来遍历它:
while(!st.empty()) {
cout << st.top();
st.pop();
}
循环方法存在的问题:
template <typename T>
void traverse_stack(stack<T> & st) {
if(st.empty())
return;
T x = st.top();
cout << x << " ";
st.pop();
traverse_stack(st);
st.push(x);
}
递归方法的优点:
递归方法存在的问题:
正如您所提到的,由于调试需要,您可能需要打印一些内容。也许以下内容对您有帮助:
// Example program
#include <iostream>
#include <string>
#include <stack>
#include <vector>
#include <algorithm>
template <typename T>
void StackDebug(std::stack<T> s)
{
std::vector<T> debugVector = std::vector<T>();
while (!s.empty( ) )
{
T t = s.top( );
debugVector.push_back(t);
s.pop( );
}
// stack, read from top down, is reversed relative to its creation (from bot to top)
std::reverse(debugVector.begin(), debugVector.end());
for(const auto& it : debugVector)
{
std::cout << it << " ";
}
}
int main()
{
std::stack< int > numbers;
numbers.push( 9 );
numbers.push( 11 );
StackDebug(numbers);
}
std::vector
,并使用push_back(),pop_back()
。#include <stack>
using std::stack;
stack< int > numbers;
numbers.push( 1 );
numbers.push( 2 );
while ( not numbers.empty( ) )
{
int number = numbers.top( );
numbers.pop( );
}
可以编写一个简单的包装器,覆盖STL的std::stack
并迭代基础容器,因为引用自参考资料:
容器必须满足SequenceContainer的要求
可以通过受保护成员c
访问此容器,因此类似于this的内容可能适用于您的情况:
#include <stack>
#include <iostream>
#include <iterator>
template <typename T, typename Container = std::deque<T>>
struct DebugStack : private std::stack<T, Container> {
auto& push(T& elem) {
std::stack<T>::push(elem);
return *this;
}
auto& push(T&& elem) {
std::stack<T>::push(elem);
return *this;
}
auto& pop() {
std::stack<T>::pop();
return *this;
}
T top() {
return std::stack<T>::top();
}
void print() {
auto const& container = std::stack<T>::c;
//T should be printable
std::copy(begin(container), end(container), std::ostream_iterator<T>(std::cout, " "));
std::cout<<'\n';
}
};
int main() {
{
DebugStack<int> stack;
stack.push(1).push(2).push(3).push(4);
stack.print();
stack.pop().pop().pop();
stack.print();
}
{
DebugStack<std::string> stack;
stack.push("First").push("Second").push("Third").push("Fourth");
stack.print();
stack.pop().pop().pop();
stack.print();
}
}
输出:
1 2 3 4
1
First Second Third Fourth
First
可以将auto
返回类型更改为DebugStack
(如此处所示),以使此解决方案适用于C++11
,因为自动推断返回类型是在C ++14
中引入的。
我不建议这样做,但是你可以通过指针转换来获取堆栈的值,这对编译后类在内存中的存储方式有一定的假设,总体来说不是一个好主意。
只要不改变默认的底层容器,即std::deque
,你可以:
std::stack<int>s;
s.push(1234);
s.push(789);
std::deque<int>* d;
d = (std::deque<int>*)&s;
cout << (*d)[0] << endl;
cout << (*d)[1] << endl;
在不弹出堆栈的情况下输出:
1234
789
https://en.cppreference.com/w/cpp/container/deque
内部deque是一系列“单独分配的固定大小数组”,因此在处理大量数据时比栈表现更好,但比向量表现更差。
stack<int> s,dbg; //s = not what's supposed to be
while(!s.empty()) {
cout << s.top() << " "; //print top of stack
dbg.push(s.top()); //push s.top() on a debug stack
s.pop(); //pop top off of s
}
//pop all elements of dbg back into stack as they were
while(!dbg.empty()) {
s.push(dbg.top());
dbg.pop();
}
我只是为了检查Leetcode问题中堆栈出现了什么问题而不得不这样做。显然在实际工作中,使用调试器可能更有意义。