1対1のマップがあります。値からキーを見つける最良の方法は何ですか、
つまり.
マップがこれである場合の例
キーバリュー
a 1
b 2
c 3
d 4
3に対応するキーがCであることを見つけたい.
ありがとう!
それについてできることはあまりありません。 2つのマップを操作するオプション、 Boost Multi-Index libraryのようなマルチキーマップを使用するオプション、または線形検索を実行するオプションがあります。
UPDATE:箱から出したソリューションの中で最も軽量なのは Boost.Bimap で、双方向マップの略です。
Map<X,Y>
があるとします。 2番目の構造、おそらく逆ルックアップを有効にしますが、ストレージオーバーヘッドの倍増を回避するmap<Y*,X*,Deref>
を構築します。ポインターを使用すると、各XとYを2回保存する必要がないためです。 2番目の構造体には、最初の構造体へのポインターがあります。
最も直接的な方法は、値とキーが逆になる並列マップを維持することです(関係は1対1であるため)。
別の解決策は、(あまり知られていない?) Boost.Bimap を使用することです。
Boost.Bimapは、C++用の双方向マップライブラリです。 Boost.Bimapを使用すると、両方のタイプをキーとして使用できる連想コンテナを作成できます。
bimap<X,Y>
は、std::map<X,Y>
とstd::map<Y,X>
の組み合わせと考えることができます。標準コンテナの使用方法を知っている場合、bimapの学習曲線はほぼ平坦です。 Boost.BimapでのSTLの命名スキームのマッピングに多大な努力が注がれました。ライブラリは、一般的なSTLコンテナに一致するように設計されています。
マップが巨大であるか、線形検索が遅すぎることを知る他の方法がない限り、線形検索から始めます。
#include <iostream>
using std::cout;
#include <map>
using std::map;
#include <algorithm>
using std::find_if;
#include <boost/assign/list_of.hpp>
using boost::assign::map_list_of;
typedef map<char, int> Map;
typedef Map::key_type Key;
typedef Map::value_type Pair;
typedef Map::mapped_type Value;
struct Finder {
const Value v;
Finder(const Value& v) : v(v) {}
bool operator()(const Pair& p) {
return p.second == v;
}
};
Map m = map_list_of('a', 1)('b', 2)('c', 3)('d', 4)('e', 5);
int main() {
Pair v = *find_if(m.begin(), m.end(), Finder(3));
cout << v.second << "->" << v.first << "\n";
}
ラムダを使用する上記の@Rob variationの回答のバリエーション:
map<char, int> m = {{'a', 1}, {'b', 2}, {'c', 3}, {'d', 4}, {'e', 5}};
int findVal = 3;
auto it = find_if(m.begin(), m.end(), [findVal](const Pair & p) {
return p.second == findVal;
});
if (it == m.end()) {
/*value not found*/
cout << "*value not found*";
}
else {
Pair v = *it;
cout << v.second << "->" << v.first << "\n";
}
(ここに貢献してくれた@Nawazに感謝します: https://stackoverflow.com/a/19828596/1650814 )
これは本当に古い質問ですが、このコードプロジェクトの記事( http://www.codeproject.com/Articles/3016/An-STL-like-bidirectional-map )はかなり良い例です双方向マップ。
これは、それがいかに簡単かを示すサンプルプログラムです。
#pragma warning(disable:4503)
#include "bimap.h"
#include <iostream>
#include <string>
using codeproject::bimap;
int main(void)
{
bimap<int,std::string> bm;
bm[1]="Monday";
bm[2]="Tuesday";
bm[3]="Wednesday";
bm[4]="Thursday";
bm[5]="Friday";
bm[6]="Saturday";
bm[7]="Sunday";
std::cout<<"Thursday occupies place #"<<bm["Thursday"]<<
" in the week (european style)"<<std::endl;
return 0;
}
std::map
キーから値まで、次の関数は逆ルックアップテーブル、std::map
値からキーへ。
/// Given a map from keys to values, creates a new map from values to keys
template<typename K, typename V>
static map<V, K> reverse_map(const map<K, V>& m) {
map<V, K> r;
for (const auto& kv : m)
r[kv.second] = kv.first;
return r;
}