反向地图查找

时间:2011-04-21 19:50:33

标签: c++ stl map

我有1对1的地图。从值中找到键的最佳方法是什么

例如,地图是否为

关键值

a    1
b    2
c    3 
d    4

我希望能够找到对应于3的密钥是C.

谢谢!

8 个答案:

答案 0 :(得分:30)

你无能为力。您可以选择使用两张地图,使用多关键地图,例如来自Boost Multi-Index库的地图,或进行线性搜索。

更新:最轻量级的开箱即用解决方案似乎是Boost.Bimap,代表双向地图。

答案 1 :(得分:12)

假设您有地图<X,Y>。构建第二个结构,可能是一个映射<Y*,X*,Deref>,它允许反向查找,但避免了双倍的存储开销,因为使用指针,不需要存储每个X和Y两次。第二个结构只是指向第一个结构。

答案 2 :(得分:8)

最直接的方法是维护一个平行映射,其中值和键被反转(因为关系是一对一的)。

答案 3 :(得分:6)

另一个解决方案是使用(鲜为人知的?)Boost.Bimap

  

Boost.Bimap是双向地图   C ++库。随着Boost.Bimap你   可以创建关联容器   这两种类型都可以用作关键。一个   bimap<X,Y>可以被视为一个   std::map<X,Y>和a的组合   std::map<Y,X>。学习曲线   如果你知道如何,bimap几乎是平的   使用标准容器。一个伟大的   已付出努力   映射STL的命名方案   在Boost.Bimap。图书馆是   旨在匹配常见的STL   容器

答案 4 :(得分:4)

除非地图很大,或者您还有其他方式知道线性搜索太慢,我会从线性搜索开始:

#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";
}

答案 5 :(得分:3)

@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

答案 6 :(得分:2)

我知道这是一个非常古老的问题,但这个代码项目文章(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;
    }

答案 7 :(得分:1)

给出从键到值的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;
    }