【问题标题】:C++ - Sort map based on values, if values same sort based on keyC ++ - 根据值对映射进行排序,如果值基于键进行相同排序
【发布时间】:2022-10-28 20:01:18
【问题描述】:

我遇到了一个问题,我需要存储两个值,一个 id 和另一个它的影响,并且 id 应该是随机访问的。也应该根据影响力排序,如果两个影响力相同,则根据id排序。考虑到这些事情,我使用了地图,但有没有办法实际做到这一点?

我在比较器和地图下方尝试过,但它给出了错误

struct cmp
{
 bool comparator()(const pair<int,int>a,const pair<int,int>b)
 {
    if(a.second==b.second) return a.first<b.first;
    else return a.second<b.second;
 }
};

unordered_map<int,int,cmp>m;

【问题讨论】:

  • std::map 调用它与它存储的 std::pairs 的 first 进行比较
  • std::map 基于键排序。
  • 抱歉,我使用了 unordered_map ,在问题中更改了它
  • unordered_map 使用 std::hash on钥匙默认情况下,因此它也不适合您的用例。您可能需要一个集合而不是地图。
  • @learner 基本上不可能有一个按某个值排序的容器,而该值也是可变的。如果更改该值,容器可能会变得未排序。您需要删除旧值并重新插入新值。

标签: c++ dictionary stl


【解决方案1】:

据我了解,您想要一个按一个值排序但可以快速被另一个值索引的集合。这两点是矛盾的。按键值对集合进行排序可以更快地按该键值进行索引。没有简单的方法可以同时以两种不同的方式快速索引一个集合。请注意,我说的是“快速可索引”,而不是谈论随机访问。那还是一个不同的概念。

简而言之,您需要两个集合。您可以有一个存储影响-ID 对并按影响排序的主存储,以及一个存储 ID 并将它们映射到主集合的辅助存储。有很多选择;这是一个:

std::set<std::pair<int,int>> influences;
std::unordered_map<int, decltype(influences)::iterator> ids;

插入影响-ID 对时,您可以先插入influence,然后将迭代器带到该新元素并将其与 ID 一起插入。

另一种解决方案是保留影响-ID 对的主要集合,但这次按 ID 排序(并在需要从 ID 获取影响时对其进行二进制搜索),并维护一个排列索引数组,告诉您在什么索引如果按影响力排序,则主集合的元素将是。像这样的东西:

std::vector<std::pair<int,int>> influences;
// insert all elements sorted by ID
std::vector<decltype(influences)::size_type> sorted_indices;
// now sort by influences but modifying `sorted_indices` instead.

Relevant question

如果 ID 都是从 0 到 N,你甚至可以只用 ID 索引影响:

std::vector<int> influences; // influences[id] is the influence value corresponding to id

这会给你random access

“正确”的选择取决于您可能拥有的许多其他可能的限制。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-12
    • 1970-01-01
    • 1970-01-01
    • 2015-07-17
    • 2021-05-17
    • 1970-01-01
    • 1970-01-01
    • 2013-05-14
    相关资源
    最近更新 更多