【问题标题】:what is the Big O( ) order of std::queue::size?std::queue::size 的大 O() 顺序是什么?
【发布时间】:2014-03-09 22:51:42
【问题描述】:

std::queue 类不清楚size 成员函数的复杂性。它似乎是基于当时使用的数据结构实现。

有人会假设sizeO(C),但它完全有可能是O(N)。显然,我可以保持自己的尺寸,但我宁愿直接打电话给size

(问题已修改):既然deque是默认容器,那么std::deque::size()的O()是多少?

【问题讨论】:

  • 所有标准容器的size() 函数必须是常数时间。请参阅 [container.requirements.general]。
  • C++11 要求所有容器的 size() 为 O(1)。不过,我相信这在以前不是强制性的。
  • @chris Not forward_list.
  • @juanchopanza,好点子。参考资料(和标准)甚至明确表示它满足所有要求,但 size()

标签: c++ data-structures queue big-o


【解决方案1】:

至少自 C++11 起,std::queue::sizeis constant 的复杂度:O(1)。

这是由std::queue 的底层容器根据§23.6.3.1/1 必须满足SequenceContainer 的要求而得到保证的,该要求继承Container 的要求,而Container 的要求反过来,根据 §23.2.1,要求成员函数 size 具有恒定的时间复杂度。

【讨论】:

  • 我很高兴听到这个消息,但想了解更多关于我刚刚发现的这个消息。 stackoverflow.com/questions/7808916/…
  • 我不认为这是有保证的。
  • 没错。我对此有点困扰。所以让我更明确一点:std::queue 的 size() 的顺序是什么,换句话说,默认的后备存储。
  • @MarkGerolimatos 在这种情况下,它是恒定的时间。
  • @juanchopanza 是的,forward_list 是一只奇怪的鸭子。但是它无论如何都不满足queue的底层容器的要求,因为它没有push_back'
【解决方案2】:

在这里总结非常好的答案:

  • C++11:O(1) (@Jeffrey)
  • C++98:未强制,需要基于容器类做实验
  • 带有默认容器的 C++98:std::queue 的默认容器 是 std::deque,它通过减去两个来计算大小 迭代器,不是 O(1),但至少是O(C)。 (@juanchopanza)

因此,如果您需要确保 C++98 中 size() 的 O(1)-ness,您必须自己计算。

如果可以的话,我想踏上我的肥皂盒,感谢 C++11 小组关闭了这个可怕的规范漏洞。许多语言/库(例如 Scala)都煞费苦心地定义运算符的 BIG-O。鉴于 C++ 的主要用例是性能,我发现这种缺乏规范令人惊讶。必须检查标头代码以确定 std 类的性能特征是完全不能接受的。

【讨论】:

  • 我同意你的观点。
【解决方案3】:

std::queue::size 在 C++11 23.6.3.1/1 中完全指定:

size_type size() const { return c.size(); }

其中cprotected 数据成员,其类型是第二个模板参数的类型。 Ergo,它的复杂度正是上述模板参数的size 成员函数的复杂度。默认值为 std::deque<T> - 其中 T 是传递给 std::queue 的第一个模板参数 - 除非另有说明,否则所有容器都具有默认的 O(1) 复杂性要求(根据 23.2.1 中的表 96)。

【讨论】:

    【解决方案4】:

    复杂度是常数 O(1)。

    常量(在底层容器上调用大小)。 http://www.cplusplus.com/reference/queue/queue/size/

    【讨论】:

      【解决方案5】:

      这可能取决于您使用的实现,最好自己检查一下。希望检查头文件并不难。尽管较新的标准要求它应该保持不变,但这是唯一确定的方法。举一个值得注意的例子,gcc 的 libstdc++ 对于std::list 仍然有 O(n)。

      【讨论】:

      • 哇。对于图书馆,尤其是 STD,“使用源 Luke”并不是一个令人愉快的答案。然而,很高兴听到在 C++11 中的事情更加严格。
      • @MarkGerolimatos 澄清一下:默认队列中的size() 是否为常数时间依赖于实现。标准规定默认容器曾经是std::deque,而std::deque::size 被限制为常数时间。
      • 确实不是。然而,粗略地引用一本 DMV 手册,“不允许司机碾过你的事实并不能真正阻止他们这样做”。
      • 另一方面,谁愿意在这样一个基本级别上使用不符合标准的实现?
      • 我相信 C++03 从来不需要这个。这个问题既没有提到任何具体的标准,也没有提到任何具体的实现。因此,在这种情况下,我能提供的唯一答案是,从轨道上使用核武器是唯一可以确定的方法。
      猜你喜欢
      • 2011-12-10
      • 2010-09-20
      • 1970-01-01
      • 2016-08-14
      • 2015-12-22
      • 1970-01-01
      • 1970-01-01
      • 2019-08-07
      • 1970-01-01
      相关资源
      最近更新 更多