【问题标题】:C++ set: counting elements less than a valueC ++ set:计数小于一个值的元素
【发布时间】:2023-03-25 03:38:01
【问题描述】:

假设我有一个 STL set <int> s 和一个 int x,我如何计算 s 中小于 x 的元素数量?

我正在寻找O(log n)(或类似的;任何比O(n) 更好的解决方案);

我已经知道std::distance(s.begin(), s.lower_bound(x)),但我相信那是O(n),因为sets 不是随机访问的。

【问题讨论】:

  • 你不能用标准的 C++ 集来做到这一点。
  • 为什么不使用支持这些排序统计的二叉搜索树呢?如果是红黑BST,即使在最坏的情况下也能保证log(n)的性能。
  • flat set 是否适合您的需求?
  • 顺便说一句,您不需要自己实现增强树。有“GNU Policy-Based STL”结构。类似这样的东西也被提议包含在 Boost 中。
  • @Abody97:是的,这就是成本,但有很多好处。您需要对其进行测试,看看它对于您的特定应用程序是否值得。根据我自己的经验,连续存储的好处往往超过线性插入和删除的成本。

标签: c++ performance algorithm stl complexity-theory


【解决方案1】:

您需要的是“订单统计树”。它本质上是一个增强(二进制搜索)树,支持附加操作rank(x),它为您提供具有小于或等于元素x 的键的元素数量。第 14 章 Cormen、Leiserson、Rivest、Stein; “算法简介”应该为您提供算法背景。

web 上也有一些实现。

【讨论】:

    【解决方案2】:

    我认为这是不可能的。您的 STL 集是基于树的结构,因此即使只是检查元素的存在也是 O(log n)。您的树的节点不会将其子分支的大小存储在任何字段中(据我所知),因此计算具有某些不直接遵循用于构建树的规则的属性的节点所需的操作数不能更小超过这些节点的数量。由于您事先不知道有多少节点的值小于 x,因此最坏情况下的性能是所有节点都小于 x 时,这意味着 O(n) 最坏情况复杂度。即使值 x 在树中,您也需要 O(log n) 操作才能找到该节点,但随后需要访问其所有左后代才能对它们进行计数,因此复杂度取决于匹配节点的数量,即 O( n) 在最坏的情况下。也许在树的节点中添加额外的数据,可以做得更好。

    【讨论】:

      【解决方案3】:

      作为对我的评论的跟进:使用红黑二叉搜索树(而不是集合),如果每个节点都存储以该节点为根的节点数(每次插入/删除节点时更新),那么您可以非常快地获得“大于/小于 X 的节点数”统计数据。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多