逆マッピングを行う必要があります。 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";
}
はあなたのコードの一部を提供してください – Sugar