【问题标题】:How can I clear a stack in c++ efficiently?如何有效地清除 C++ 中的堆栈?
【发布时间】:2017-03-05 05:52:14
【问题描述】:

我有一个名为 pages 的 c++ 堆栈。 由于我没有 clear() 函数来清除堆栈,我编写了以下代码:

stack<string> pages;
//here is some operation
//now clearing the stack
while(!pages.empty())
    pages.pop();

现在我的问题是:有没有更有效的方法来清除堆栈?

【问题讨论】:

  • 您是否尝试过为您的堆栈分配一个空堆栈?
  • 不,谢谢你的建议(y)
  • 你问的是效率。创建新堆栈可能不会更有效,因为它会导致更多的堆分配。底层容器默认为deque。如果您使用dequevector,您将丢弃您已经为容器申请的分配内存,否则可以重复使用。
  • @PaulRooney 可以反过来使用相同的参数。在循环中使用微不足道的析构函数销毁类型可能比(可能被省略的)分配更浪费。而且,保留分配的内存可能与他想要的相反。一切都取决于做出明智的决定。
  • 当然。我并不是说一个比另一个更好,只是根据 Op 的需求来考虑。

标签: c++


【解决方案1】:

一般来说,您无法在 O(1) 中清除复制容器,因为您需要销毁副本。可以想象,一个模板化的复制容器可能有一个在 O(1) 时间内清除的部分特化,该特化是由指示所包含对象类型的特征触发的,该特征指示包含的对象的类型具有微不足道的析构函数。

如果你想避免循环。

pages=stack<std::string>();

stack<std::string>().swap(pages);

【讨论】:

  • 有没有办法做到这一点(在 C++14 中)而不必显式声明类型?
  • 所有容器都有clear -- 除了array。这就是stack 没有clear 的原因吗?如果是这样,避免或忽略该异常不是更有用吗?使用 stack 时没有 clear 似乎很奇怪。
  • @JohnH。是的:pages = {};
  • 当我使用它时,它会清空所有其他堆栈,我不确定出了什么问题。
  • 您的所有堆栈都可能只是对一个实际对象的引用。 @约瑟夫。
【解决方案2】:

我认为没有更有效的方法。堆栈是一种定义明确的数据类型,专门设计用于在 LIFO 上下文中操作,而不是立即清空。 为此,您可以使用vectordeque(或list),它们基本上是底层容器; stack 实际上是一个容器适配器。请参阅此C++ Reference 了解更多信息。

如果你别无选择,而你必须使用堆栈,那么你这样做的方式并没有错。无论哪种方式,如果元素被构造,则必须销毁它们,无论您分配一个新的空堆栈还是弹出所有元素或其他任何方式。

我建议改用vector;它确实有你需要的操作:

  • 大小(或调整大小)
  • push_back
  • pop_back
  • 返回
  • 清除

只是更方便,所以你可以使用clear 方法。不确定使用vector 是否真的更高效;堆栈操作基本相同。

【讨论】:

    【解决方案3】:

    给它分配一个新的空栈怎么样?

    pages = stack<string>();
    

    它不会一个一个地删除元素,它使用移动分配,因此它有可能非常快。

    【讨论】:

      【解决方案4】:

      子类化 std::stack 并实现一个像这样的简单 clear() 方法,访问底层容器 c 怎么样?

      public:
          void clear() { c.clear(); }
      

      【讨论】:

      • 这是非标准的,对于a few reasons 来说是个坏主意。底层容器名称会因实现而异,并且不能保证实现不依赖于底层容器以外的某些变量,清除它可能会破坏堆栈的状态。
      • 尽管对这个答案提出了批评,但这似乎是最有效的解决方案,如果不是最便携的话。
      猜你喜欢
      • 2015-04-13
      • 2020-04-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-11
      • 2016-12-16
      • 2011-08-17
      相关资源
      最近更新 更多