c++ 如何创建一个std::unordered_map,但有两个键?

u5i3ibmn  于 2024-01-09  发布在  其他
关注(0)|答案(2)|浏览(158)

我有一个项目列表,每个项目在列表中都有一个UID和一个索引。根据情况,我只能通过项目的UID或索引访问项目,永远不会两者兼而有之。为了存储这些项目,我需要一个可以有两个键的数据类型,并且行为类似于std::unordered_map。类似于这样:std::multi_unordered_map<int, int, ItemType> items;,其中两个int都是键。重要的是我应该只需要两个键中的一个来访问项目。
我看过几个版本的“多键Map”,但没有一个适合我的用例。

  • Tessil's library很棒,但它只维护插入顺序(这很好,因为它总是等于元素的索引),并且不允许使用它访问元素。
  • This question's answer有一个很好的解决方案,但它需要同时了解两个密钥,而我没有。This GeeksForGeeks article也有同样的问题。

是否有针对此问题的库或公认(标准)解决方案?
我能想到的唯一解决办法是这样的:

  1. std::unordered_map<int, int> a; //UID, intermediate_value
  2. std::unordered_map<int, int> b; //index, intermediate_value
  3. std::unordered_map<int, ItemType> items; //intermediate_value, item

字符串
然后,我可以使用相关的结构访问中间值,然后使用中间值来查找项目。当然,我相信我可以使用std::vector而不是std::unordered_map来使其更有效,但无论如何,这是很多额外的步骤,我想避免。
另外,我正在寻找小的库(像我之前提到的Tessil's)。我更喜欢避免像boost这样的东西。

vohkndzv

vohkndzv1#

我可能会将项目本身存储在一个vector中,然后从UID到索引创建一个unordered_map到vector中,类似于这样:

  1. template <class UID, class Item>
  2. class DualMap {
  3. std::unordered_map<UID, std::size_t> m;
  4. std::vector<Item> items;
  5. public:
  6. // insert an item, return its index:
  7. std::size_t insert(UID id, Item item) {
  8. items.push_back(item);
  9. m.insert(id, items.size()-1);
  10. return items.size()-1;
  11. }
  12. Item *find_by_id(UID id) {
  13. auto pos = m.find(id);
  14. if (pos == m.end())
  15. return nullptr;
  16. return &items[pos->second];
  17. }
  18. Item *find_by_index(std::size_t index) {
  19. return items[index];
  20. }
  21. };

字符串
这与你在问题中概述的方法没有 * 显著 * 不同,但仍然让我觉得更干净,更简单。

展开查看全部
5hcedyr0

5hcedyr02#

也许一个变量可以作为你的键,因为你永远不会同时拥有UID和索引

  1. struct UID {
  2. int value;
  3. };
  4. struct Index {
  5. int value;
  6. };
  7. std::unordered_map<std::variant<UID, Index>, ItemType> items;

字符串

更新

这是一个不完整的提案。请参阅接受提案。

展开查看全部

相关问题