关于c 11:在unordered_set上排序

Sorting on unordered_sets

我有一个每帧创建的项目列表,需要对其进行排序。
每个 Item 要排序的第一个成员变量是 unordered_set.

我已将其移至系统中随处可见的有序集合,以便我可以在项目列表中对其进行排序。但是我在另一个代码中遇到了性能问题。

记住,每个项目都将被销毁并在每帧的基础上重新创建,我能做些什么来将它们保存在 unordered_set 中并对其进行排序?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class item
{
    public:
    unordered_set< int > _sortUS;
    int _sortI;
    //Other members to sort
    bool operator<( const item& that ) const
    {
        if( _sortI != that._sortI )
        {
            return _sortI < that._sortI;
        }
        else if( _sortUS != that._sortUS )
        {
            return ??? // this is what I need. I don't know how to compare these without converting them to sets
        }
    }
};


给定 std::unordered_set<Key, Hash> 对于任意可散列的 Key,您可以定义

1
2
3
4
5
6
7
8
9
template<class Key, class Hash = std::hash<Key>>
bool operator< (std::unordered_set<Key, Hash> const& L, std::unordered_set<Key, Hash> const& R)
{
    return std::lexicographical_compare(
        begin(L), end(L), begin(R), end(R),
        [](Key const& kL, Key const& kR) {
        return Hash()(kL) < Hash()(kR);    
    });
}

将使用 Key 的哈希索引的顺序。然后您可以在 item

上定义排序

1
2
3
4
bool operator< (item const& L, item const& R)
{
     return std::tie(L.sortI, L.sortUS) < std::tie(R.sortI, R.sortUS);
}

std::tie 将从对 item 成员的引用中生成一个 std::tuple,以便您可以使用 std::tuple.

中的 operator<

注意:您可以轻松证明上述比较是 StrictWeakOrder(std::sort 的要求),因为 std::tuple 比较和 lexicographical_compare 都具有此属性。

然而,unordered_set 的排序在其他方面非常不寻常。

  • 散列键索引与您迭代元素的顺序不对应(有一些模运算将散列键映射到容器中的索引)
  • 将元素添加到 unordered_set 可能导致先前排序的重新散列和无效