C++ 交换堆栈上的两个值

C++ 交换堆栈上的两个值,c++,stack,swap,C++,Stack,Swap,我想交换std::stack顶部的两个值。有没有比下面更好的方法 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); } void swap_top(标准::堆栈和堆栈) { 双a=stack.top(); st

我想交换
std::stack
顶部的两个值。有没有比下面更好的方法

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);
}
void swap_top(标准::堆栈和堆栈)
{
双a=stack.top();
stack.pop();
double b=stack.top();
stack.pop();
栈.推(a);
堆栈推送(b);
}

这几乎是实现这一点的标准方法,将“复杂”代码隔离到函数中,这样您就不必再担心它了。当然,作为一个模板函数,它会更好,这样它就不会绑定到双类型的堆栈


或者,您可以对堆栈进行子分类(real
is-a
子类或
has-a
变体),并作为额外功能提供该功能。但是您仍然需要编写该代码以及子分类所需的所有代码:-)

您可以使用较少的堆栈操作,但使用
std::swap
,尽管我怀疑它会更快:

double a = stack.top();
stack.pop();
std::swap(a, stack.top());
stack.push(a);

或者不要直接使用
堆栈
,而是直接使用底层容器(例如
deque
vector
、或
list
)。

我不知道这是否是一种更好的方法,但至少是一种替代方法

void swap_top(std::stack<double>& stack)
{
  double a = stack.top();
  stack.pop();

  swap( a, stack.top() ); 
  stack.push(a);
}
void swap_top(标准::堆栈和堆栈)
{
双a=stack.top();
stack.pop();
swap(a,stack.top());
栈.推(a);
}

对于普通堆栈,没有更好的方法了

有趣的是,
堆栈
适配器实际上将底层容器作为受保护的成员公开。这意味着您可以执行以下操作:

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);
  }
};
模板
类stack_ex:public std::stack{
公众:
使用stack_ex::stack::stack;
void swap_top(){
auto last=c.rbegin();
最后一次之前自动=标准::上一次(最后);
标准::国际热核实验堆交换(最后一次,在最后一次之前);
}
};

没有,我会解释原因


想象一下,有一堆盘子,你只能看到上面的一个。从顶部第二个位置接触板的唯一方法是移除顶板。现在看你把顶板拿走了。先前从顶部算起第二个的板块现在位于顶部。如何在不首先从堆栈中提取的情况下修改此板?这是不可能的,所以你提取它。此时,交换元素的最快方法是简单地将它们放回原处,但其提取顺序与提取顺序相反。这就是你所拥有的。

你可以排一个队

堆栈: 50 40 30 20 十,

在队列中弹出前两个元素和插入器->->


队列:50 40好吧,你可以写一个泛型函数,但除此之外。。。不,这不是真正的问题。但我担心表现。这是一个非常小的事情的很多说明…@Caduchon,我严重怀疑你会找到一个更快的方法,除非你实现自己的队列,根据你的用例定制。我也不认为表现会是一个真正的问题。如果你担心,请记住优化的第一条法则:衡量,不要猜测!我正在写一个能够计算数学表达式的执行模块。堆栈非常适合这样做!:-)@Caduchon显然并不完美,因为您需要高效地交换元素。swap是我决定在堆栈上使用的基本命令之一,用于简化我的基本语言。例如,我通过调用SWAP and LESS计算操作符>,或者使用NEG SWAP NEG或NEG计算and。如果我有性能问题,我的解决方案可能是添加更多的基本命令。很好!直到某物。只是我认为它应该是
std::next
,而不是
prev
。非常复杂,但很有趣的解决方案!