如何在O(logn)中设置stl中元素的等级

时间:2013-08-07 03:05:21

标签: c++ algorithm data-structures stl

我想在stl集中找到元素的等级。我能够从头开始遍历那个元素并找出它的等级,但是这就是O(n)。有没有找到O(logn)等级的方法。

5 个答案:

答案 0 :(得分:4)

没有;平衡树不需要存储每个节点的后代数,这对于distance( s.begin(), iter )和迭代器std::set s更快速计算iter是必需的(我想你的意思是这个) 。因此,除了逐项计算项目之外,信息根本不存在。

如果您需要执行许多此类计算,请将set复制到排序的随机访问序列,例如vectordeque,但随后修改序列会变得昂贵。

执行您所问的内容的树数据结构可能存在于某个免费库中,但我不知道它。

答案 1 :(得分:2)

@Potatoswatter建议的排序向量的功能由flat_setBoost.Container提供。该文档列出了以下权衡

  • 比标准关联容器更快的查找
  • 比标准关联容器更快的迭代次数
  • 减少小对象(以及使用shrink_to_fit时的大对象)的内存消耗
  • 改进了缓存性能(数据存储在连续内存中)
  • 非稳定迭代器(插入和擦除元素时迭代器无效)
  • 无法存储不可复制和不可移动的值类型
  • 比标准关联容器更弱的异常安全性(复制/移动构造函数可以在删除和插入时移动值时抛出)
  • 比标准关联容器(特别是对于不可移动类型)更慢的插入和擦除

答案 2 :(得分:2)

您要找的是Order Statistic Tree。如果您使用的是GNU C ++库,则应该有一个可用于构建订单统计树的扩展。下面给出一个简短的例子:

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <cstdio>
using namespace std;
using namespace pb_ds;

typedef tree<
int, /* key type */
null_mapped_type, /* value type */
less<int>, /* comparison */
rb_tree_tag, /* for having an rb tree */
tree_order_statistics_node_update> order_set;

int main()
{
    order_set s;
    s.insert(10);
    s.insert(20);
    s.insert(50);
    s.insert(25);

    printf("rank of 25 = %d\n", s.order_of_key(25));
}

输出应为rank of 25 = 2。有关更多示例,您可以看到this file

答案 3 :(得分:1)

如果您使用的是GCC,实际上是一个内置的解决方案,但是Subhasis Das的答案有些过时了,由于更新,它不适用于较新版本的GCC。标头现在是

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;

并且集合结构是

typedef tree<
int, 
null_type, 
std::less<int>, 
rb_tree_tag, 
tree_order_statistics_node_update> ordered_set;

或者,如果需要多集,则可以用std::less<int>代替std::less_equal<int>

这是按等级查找的演示:

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
#include <iostream>

typedef tree<int, null_type, std::less_equal<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;

int main()
{
    ordered_set s;
    s.insert(10);
    s.insert(20);
    s.insert(50);
    s.insert(25);

    for(int i=24; i<=26; i++) std::cout << "Rank of " << i << ": " << s.order_of_key(i) << std::endl;
}

答案 4 :(得分:0)

我认为C ++中的STL集合中有一个lower_bound函数,可用于查找集合中元素的等级。看看https://www.geeksforgeeks.org/set-lower_bound-function-in-c-stl/