您需要提供反向映射。有很多方法可以做到这一点,包括multimap,但是如果您的映射在创建后没有被修改,一个简单的方法是迭代映射并建立反向映射。在反向映射中,您映射值 -> 键列表。
下面的代码使用std::unordered_map 将std::pair<int, int>(原始映射中的值)映射到std::vector<int>(原始映射中的键列表)。反向地图的搭建简单明了:
std::unordered_map<Point, std::vector<int>, hash> r;
for (const auto& item : m) {
r[item.second].push_back(item.first);
}
(请参阅完整示例了解hash 的定义)。
无需担心密钥是否存在;当您尝试使用 r[key] 表示法访问该密钥时,它将被创建(并且 id 的向量将被初始化为空向量)。
这个解决方案的目标是简单;如果您需要这样做并且不关心性能、内存使用或使用 Boost 等第三方库,这是一个可行的解决方案。
如果您确实关心这些事情,或者您正在修改地图同时在两个方向上进行查找,您可能应该探索其他选项。
Live example
#include <iostream>
#include <map>
#include <unordered_map>
#include <vector>
// Define a point type. Use pair<int, int> for simplicity.
using Point = std::pair<int, int>;
// Define a hash function for our point type:
struct hash {
std::size_t operator()(const Point& p) const
{
std::size_t h1 = std::hash<int>{}(p.first);
std::size_t h2 = std::hash<int>{}(p.second);
return h1 ^ (h2 << 1);
}
};
int main() {
// The original forward mapping:
std::map<int, Point> m = {
{1, {2, 3}},
{5, {6, 2}},
{12, {2, 3}},
{54, {4, 4}},
{92, {6, 2}}
};
// Build reverse mapping:
std::unordered_map<Point, std::vector<int>, hash> r;
for (const auto& item : m) {
r[item.second].push_back(item.first);
}
// DEMO: Show all indices for {6, 2}:
Point val1 = {6, 2};
for (const auto& id : r[val1]) {
std::cout << id << " ";
}
std::cout << "\n";
// DEMO: Show all indices for {2, 3}:
Point val2 = {2, 3};
for (const auto& id : r[val2]) {
std::cout << id << " ";
}
std::cout << "\n";
}