问题
In c++ how can I print out the contents of my stack and return its size?
std::stack<int> values;
values.push(1);
values.push(2);
values.push(3);
// How do I print the stack?
回答1:
You could make a copy of the stack and pop items one-by-one to dump them:
#include <iostream>
#include <stack>
#include <string>
int main(int argc, const char *argv[])
{
std::stack<int> stack;
stack.push(1);
stack.push(3);
stack.push(7);
stack.push(19);
for (std::stack<int> dump = stack; !dump.empty(); dump.pop())
std::cout << dump.top() << '\n';
std::cout << "(" << stack.size() << " elements)\n";
return 0;
}
Output
19
7
3
1
(4 elements)
See it live here: http://liveworkspace.org/code/9489ee305e1f55ca18c0e5b6fa9b546f
回答2:
Both std::stack and std::queue are wrappers around a general container. That container is accessible as the protected member c. Using c you can gain efficient access to the elements; otherwise, you can just copy the stack or queue and destructively access the elements of the copy.
Example of using c:
#include <iostream> // std::wcout, std::endl
#include <stack> // std::stack
#include <stddef.h> // ptrdiff_t
using namespace std;
typedef ptrdiff_t Size;
typedef Size Index;
template< class Elem >
Size nElements( stack< Elem > const& c )
{
return c.size();
}
void display( stack<int> const& numbers )
{
struct Hack
: public stack<int>
{
static int item( Index const i, stack<int> const& numbers )
{
return (numbers.*&Hack::c)[i];
}
};
wcout << numbers.size() << " numbers." << endl;
for( Index i = 0; i < nElements( numbers ); ++i )
{
wcout << " " << Hack::item( i, numbers ) << endl;
}
}
int main()
{
stack<int> numbers;
for( int i = 1; i <= 5; ++i ) { numbers.push( 100*i ); }
display( numbers );
}
回答3:
The only way to print the elements of a std::stack without popping them, is to write an adapter that extends std::stack (here's an example). Otherwise, you should replace your stack with a std::deque.
回答4:
http://www.cplusplus.com/reference/stl/stack/ for the size it's easy use :
cout << mystack.size();
For the rest i didn't see anything about in the doc but you should print the content of your stack when you push it, or have a list with it to keep a record of the element just in order to print it, don't forget to delete it when you're done testing
回答5:
Hm, a nearly 10 years old question. Anyway, here an additional answer.
First: The size of a stack is given by std::stack.size().
Then, in modern C++ the STL with algorithms is used more and more. So the following solution makes use of that. The precondition is that a stack uses contiguous memory. That is guaranteed at the moment.
Output is done via a one liner.
See the following example:
#include <vector>
#include <stack>
#include <iostream>
#include <algorithm>
#include <iterator>
#include <sstream>
using Number = int;
using UnderlyingContainer = std::vector<Number>;
using Stack = std::stack< Number, UnderlyingContainer>;
std::istringstream testData("5 8 1 4 9 3");
int main()
{
// Put the test data onto the stack
Stack stack{ UnderlyingContainer {std::istream_iterator<Number>(testData),std::istream_iterator<Number>()} };
// Print the test data
if (not stack.empty())
std::copy(&stack.top() + 1 - stack.size(), &stack.top() + 1, std::ostream_iterator<Number>(std::cout, "\n"));
return 0;
}
This is completely valid and reliable code. Here a little bit more explanation.
We want to output the data, so we copy it to an ostream_iterator. The ostream_iterator takes a reference to a stream (Yes you can put also an open ofstream) and the deliminator. Maybe you want to use a " ".
The source for the copy are 2 iterators. And, yes, pointers are iterators. And, we make use of the guaranteed contiguous memory for a std::stack. So, we simply calculate 2 pointers and hand them over to std::copy.
And if you want to use explicit iterators. Here we go . .
#include <vector>
#include <stack>
#include <iostream>
#include <algorithm>
#include <iterator>
#include <sstream>
using Number = int;
using UnderlyingContainer = std::vector<Number>;
using Stack = std::stack< Number, UnderlyingContainer>;
using StackIterator = const Number *;
std::istringstream testData("5 8 1 4 9 3");
int main()
{
// Put the test data onto the stack
Stack stack{ UnderlyingContainer {std::istream_iterator<Number>(testData),std::istream_iterator<Number>()} };
// Print the test data
// Get iterators
StackIterator end = &stack.top() + 1;
StackIterator begin = end - stack.size();
if (not stack.empty())
std::copy(begin, end, std::ostream_iterator<Number>(std::cout, "\n"));
return 0;
}
So you can create iterators for a stack. But, caveat:
The std::stack intentionally hides its elements under the hood. So, if you write-access the data, I would see it as a design fault. Read-access through const pointers/iterators is for me OK. But maybe you should better use a std::vector . . .
来源:https://stackoverflow.com/questions/12631514/how-can-i-print-out-the-contents-of-stdstack-and-return-its-size