Reputation: 5231
I want to swap the two values on the top of a std::stack<double>
. Is there a better way than the following to do that ?
void swap_top(std::stack<double>& stack)
{
double a = stack.top();
stack.pop();
double b = stack.top();
stack.pop();
stack.push(a);
stack.push(b);
}
Upvotes: 7
Views: 8328
Reputation: 174
you can take one queue and do it.
Stack: 50 40 30 20 10
pop first two element and inser in the queue ->->
Queue: 50 40 <- deueue 50 and 40 and oush to the stack then you will get
Stack 40 50 30 20 10
Upvotes: -1
Reputation: 7504
No, and I'll explain why.
Imagine there is a stack of plates where you can only see the top one. The only way you have access to the plate second from the top is if you were to remove the top plate. Now consider you have removed the top plate. The plate that was previously second from the top is now at the top. How do you modify this plate without first extracting it from the stack? It's not possible and so you extract it. At this point, the fastest way to swap the elements is to simply put them back but in the reverse order in which they were extracted. Which is what you have.
Upvotes: -1
Reputation: 72054
With a plain stack, there's no better way.
Interestingly, the stack
adapter actually exposes the underlying container as a protected member. This means that you can do this:
template <typename T, typename Container = std::deque<T>>
class stack_ex : public std::stack<T, Container> {
public:
using stack_ex::stack::stack;
void swap_top() {
auto last = c.rbegin();
auto before_last = std::prev(last);
std::iter_swap(last, before_last);
}
};
Upvotes: 12
Reputation: 311088
I do not know whether it is a better way but at least it is an alternative way.
void swap_top(std::stack<double>& stack)
{
double a = stack.top();
stack.pop();
swap( a, stack.top() );
stack.push(a);
}
Upvotes: 1
Reputation: 882226
That's pretty much the standard way to do it, isolating the "complex" code to a function so you never have to worry about it again. Of course, it would be better as a template function so it wouldn't be tied to double
-type stacks.
Alternatively you could sub-class the stack (either a real is-a
sub-class or a has-a
variant) and provide that functionality as extra. But then you'd still have to write that code as well as all the code required for sub-classing :-)
Upvotes: 2
Reputation: 41331
You can do it with less stack operations but using std::swap
, though I doubt it will be faster:
double a = stack.top();
stack.pop();
std::swap(a, stack.top());
stack.push(a);
Or just don't use stack
, use the underlying container (such as deque
, vector
, or list
) directly.
Upvotes: 5