在unordered_sets上排序

时间:2014-02-10 15:54:51

标签: sorting c++11 unordered-set

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

我已经将它移动到系统中的任何地方的有序集合中,因此我可以在项目列表中对其进行排序。但是我遇到了另一个性能受到影响的代码。

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

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
        }
    }
};

1 个答案:

答案 0 :(得分:1)

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

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

上定义排序
bool operator< (item const& L, item const& R)
{
     return std::tie(L.sortI, L.sortUS) < std::tie(R.sortI, R.sortUS);
}

std::tie将对std::tuple成员的引用进行item,以便您可以使用operator<中的std::tuple

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

但是,unordered_set的排序在其他方面非常不寻常。

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