【问题标题】:Sorting by struct data inside unordered_map按 unordered_map 中的结构数据排序
【发布时间】:2022-01-22 14:54:12
【问题描述】:

我有一个std::unordered_map<id, town_data> data,其中town_data 是一个包含不同信息的struct - 名称(字符串)、征收的税款(整数)和与首都的距离(整数)。我应该建立一个std::vector<id>,它按前面提到的距离排序,从低到高。我很难弄清楚如何有效地做到这一点。我想我可以简单地循环遍历data,通过该循环/插入创建std::map<distance, id>,按距离排序,除非地图默认排序,然后逐个键将其复制到新向量std::vector<id>。但这似乎真的很浪费。我在这里错过了一些捷径或更有效的解决方案吗?

【问题讨论】:

  • 请展示您的尝试。
  • 很高兴您能提供帮助。这就是本网站的全部目的。可惜我只能投票一次。无论如何,感谢您的良好贡献和支持活动。我不确定我还能做些什么。再次感谢您

标签: c++ vector time-complexity unordered-map


【解决方案1】:

您可以在映射中创建一个std::vector 迭代器,然后根据您的排序标准对迭代器进行排序。排序后,您可以将结果转换为std::vector<id>

创建一个std::vector 的迭代器:

    std::vector<decltype(data)::iterator> its;
    its.reserve(data.size());
    for(auto it = data.begin(); it != data.end(); ++it)
        its.push_back(it);

排序std::vector:

#include <algorithm> // std::sort, std::transform

    std::sort(its.begin(), its.end(),
              [](auto& lhs, auto&rhs) {
                  return lhs->second.distance < rhs->second.distance;
              });

最后,将其转换为std::vector&lt;id&gt;

#include <iterator> // std::back_inserter

    std::vector<id> vec;
    vec.reserve(its.size());
    std::transform(its.begin(), its.end(), std::back_inserter(vec),
                   [](auto it) {
                       return it->first;
                   });

【讨论】:

  • 谢谢伙计,我什至没有想到对迭代器本身进行矢量化和排序的可能性。非常有用的想法!
  • @JustAnotherDoomer 很高兴它有帮助!不客气!
  • 确实是更好的答案。我会通过浪费内存将地图放在一个多集中。这很好+1
【解决方案2】:

我觉得id的向量可以直接排序如下,

std::vector<decltype(decltype(data)::value_type::second_type::id)> vec;
vec.reserve(data.size());
for(auto it = data.begin(); it != data.end(); ++it)
    vec.push_back(it->second.id);
std::sort(vec.begin(), vec.end(), [&data](auto lhs, auto rhs) { return data[lhs].distance < data[rhs].distance; });

我想知道这是否比对 town_data 向量进行排序更有效,不是吗?

【讨论】:

  • 我认为没有人建议对town_data 的向量进行排序。无论如何,我会测量这个。您必须在此处的地图中进行大量查找,如果这比在排序时使用迭代器花费更多时间,我不会感到惊讶。我猜这可能取决于地图的大小。
  • 感谢您的评论。正如你所说,我不知道地图中有多少查找。我很惊讶,这让我学到了很多东西。
  • 只是怀疑。在确定有关性能的任何内容之前,我需要进行测量。无论如何我喜欢这个解决方案,因为它很简单,但我没有得到decltype(decltype(data)::value_type::second_type::id。类型定义为id 那么为什么不使用它呢?
  • 只是我不确定id是否是一个类型,我觉得在前面的答案中最好使用std::vector&lt;decltype(data)::iterator&gt;之类的类型。
猜你喜欢
  • 2015-08-13
  • 2013-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多