【问题标题】:How to sort elements in a bucket of std::unordered_set?如何对 std::unordered_set 存储桶中的元素进行排序?
【发布时间】:2018-07-26 07:11:24
【问题描述】:

在填充 STL 的 unordered_set 之后,我尝试根据特定顺序对每个存储桶中的元素进行排序(尽管容器名称相互矛盾)。众所周知,不能对容器中的元素进行任何更改,据我所知,它会阻止标准 std::sort 工作。例如下一个代码不会编译:

#include <unordered_set>
int main()
{
    std::unordered_set<int> set_;

    set_.max_load_factor(100);

    set_.insert(6);
    set_.insert(3);
    set_.insert(8);
    set_.insert(17);
    set_.insert(1);
    set_.insert(2);
    set_.insert(9);

    for (int i = 0; i < set_.bucket_count(); ++i)
    {
        std::sort(set_.begin(i), set_.end(i));
    }
}

那么,是否有解决该障碍的方法?是否可以获取一个临时排序列表,然后将其分配给初始存储桶?

【问题讨论】:

  • 很明显,您使用了错误类型的容器。
  • @NeilButterworth 不是很明显。只需要对桶中的少数元素进行排序,而不是在整个容器中进行排序
  • 这个练习的最终目标是什么?为什么要关心单个存储桶中元素的顺序?这听起来像XY problem
  • @IgorTandetnik 有一些要点。确定上面的例子是人为的,但是在我的真实代码中,有一个自定义哈希函数可以按照我需要的方式放置元素。并且同一个桶中的项目或多或少地被对待并且对它们进行排序将简化每个桶中的情况
  • 请注意,“同一桶中的元素”并不一定意味着“具有相同哈希的元素”。具有相同的哈希是足够的,但不是必要的条件。大多数时候,桶的数量比可能的不同哈希值少得多。所以我有点质疑“以我需要的方式放置元素”的说法。

标签: c++ stl hashtable unordered-map unordered-set


【解决方案1】:

没有 API 可以做你正在做的事情,因为容器暴露接口而不是实现是违反 STL 设计原则的。不能保证“对每个存储桶进行排序”通常有意义(即使在您的特定实现中是可能的)。

如果您确定需要在哈希表中“对每个存储桶进行排序”,则需要实现自己的哈希表。鉴于过多的开源实现,这并不难。在桶通常使用链表实现的地方,您可能会使用平衡二叉树。

【讨论】:

    【解决方案2】:

    “在我的真实代码中......自定义哈希函数......按照我需要的方式放置元素” - 你确定吗? - 您的自定义散列函数不直接选择存储桶 - unordered_set 将其用作其存储桶选择的 an 输入,通常执行类似 % bucket_count()&amp; (bucket_count() - 1) 之类的优化操作如果bucket_count() 始终是二的幂。而且您不一定能控制存储桶的数量 - 调用 reserve(n) 可能会将 n 舍入到例如一个附近的(不一定是下一个)素数,或者可能是二的幂。所有实现定义。也就是说,您可以在哈希函数中使用 bucket_count() 来真正控制您的密钥如何分组到存储桶中,或者只生成小于您提供给 reserve()n 的哈希值,但是当您这样做时,您还不如将索引管理到 std::vector 的键中。无论如何,足够了 - 让我们相信你确实按照你想要的方式控制哈希存储桶:如果你想要一个桶中元素的排序列表,你可以简单地使用:

    std::unordered_map<KeyOnly, AnotherContainer<KeyAndValue>> x;
    

    其中AnotherContainer 是任何容器,它要么是固有排序的(例如std::set),要么可以按照您在问题中尝试的方式在您的代码中显式排序(例如std::liststd::vector)。

    【讨论】:

    • 是的,这正是我终于来到的地方
    猜你喜欢
    • 2023-01-10
    • 2016-03-15
    • 2016-09-08
    • 1970-01-01
    • 2019-09-15
    • 1970-01-01
    • 2012-04-13
    • 2018-02-01
    • 1970-01-01
    相关资源
    最近更新 更多