在 unordered_sets 上排序

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

最佳答案

给定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 添加元素可能导致先前排序的重新散列和无效

关于在 unordered_sets 上排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21681803/

相关文章:

c++ - constexpr std::array with static_assert

c++ - std::unordered_set 的元素的迭代顺序是否保证始终相同?

c++ - constrain_hash 中的 unordered_set EXC_BAD_ACCESS

c++ - 无法将 std::unorded_set 与自定义 KeyEqual 进行比较

java - 使用 Glazed Lists 和 JXTable 进行表外列排序

c++ - 转发 C++0x 中的所有构造函数

ruby - 你能用 Ruby 优化这个降序排列的数组吗?

c++ - 为什么C++中的 `const char *`类型可以存储Unicode?

c - 需要帮助使用 qsort 对 C 中的结构数组进行排序

java - 使用 compareTo() 方法对 String 数组的 ArrayList 进行排序