反向地图查找
我有一个1比1的地图。 什么是从价值中find钥匙的最好方法,
即
例如,如果地图是这样的
核心价值
a 1 b 2 c 3 d 4
我想能够find对应于3的键是C.
谢谢!
对此你没有太多的办法。 您可以select使用两个地图,像使用Boost Multi-Index库中的多键地图一样使用多键地图,或者进行线性search。
更新:最轻量级的开箱即用解决scheme似乎是Boost.Bimap ,它代表双向地图。
假设你有一张地图<X,Y>
。 构build第二个结构,也许是一个映射<Y*,X*,Deref>
,它可以进行反向查找,但避免了双倍的存储开销,因为使用指针不需要将每个X和Y存储两次。 第二个结构只是指向第一个。
最直接的方法是维护一个平行的地图,其中的值和关键是相反的(因为关系是一对一的)。
另一个解决scheme是使用(不太知道?) Boost.Bimap :
Boost.Bimap是C ++的双向映射库。 借助Boost.Bimap,您可以创build两种types都可以用作关键字的关联容器。
bimap<X,Y>
可以认为是std::map<X,Y>
和std::map<Y,X>
。 如果您知道如何使用标准容器,bimap的学习曲线几乎是平坦的。 Boost.Bimap中的STL的命名scheme已经投入了很大的努力。 该库被devise为匹配常见的STL容器。
除非地图很大,或者你有其他的方式来知道线性search速度太慢,否则我会从线性search开始:
#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ᵩ上面的答案的变体使用lambda:
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)
我知道这是一个非常古老的问题,但是这个codeproject文章( 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; }