简体   繁体   English

反向地图查找

[英]Reverse map lookup

I have a 1 to 1 map. 我有1对1的地图。 What's the best way to find keys from values, 从值中查找键的最佳方法是什么,

ie

For examples if the map is this 例如,如果地图是这样的

KEY VALUE 核心价值

a    1
b    2
c    3 
d    4

I want to be able to find that key corresponding to 3 is C. 我希望能够找到对应于3的键是C.

Thanks! 谢谢!

There isn't much you can do about it. 你无能为力。 Your have options to work with two maps, use multi-key map like one from Boost Multi-Index library, or do linear search. 您可以选择使用两个地图,使用Boost Multi-Index库中的多键地图,或进行线性搜索。

UPDATE: The most lightweight out of the box solution seems to be Boost.Bimap , which stands for bi-directional map. 更新:最轻量级的开箱即用解决方案似乎是Boost.Bimap ,它代表双向地图。

Say you have a map <X,Y> . 假设你有一张地图<X,Y> Build a second structure, perhaps a map <Y*,X*,Deref> that enables the reverse lookup but avoids doubling the storage overhead, because, using pointers, there's no need to store each X and Y twice. 构建第二个结构,可能是一个映射<Y*,X*,Deref> ,它启用了反向查找,但避免了双倍的存储开销,因为使用指针,不需要存储每个X和Y两次。 The second structure simply has pointers into the first. 第二个结构只是指向第一个结构。

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

Another solution would be to use (the less known?) Boost.Bimap : 另一个解决方案是使用(鲜为人知的?) Boost.Bimap

Boost.Bimap is a bidirectional maps library for C++. Boost.Bimap是一个用于C ++的双向映射库。 With Boost.Bimap you can create associative containers in which both types can be used as key. 使用Boost.Bimap,您可以创建关联容器,其中两种类型都可以用作键。 A bimap<X,Y> can be thought of as a combination of a std::map<X,Y> and a std::map<Y,X> . bimap<X,Y>可以被认为是std::map<X,Y>std::map<Y,X> The learning curve of bimap is almost flat if you know how to use standard containers. 如果您知道如何使用标准容器,那么bimap的学习曲线几乎是平坦的。 A great deal of effort has been put into mapping the naming scheme of the STL in Boost.Bimap. 在Boost.Bimap中映射STL的命名方案已经付出了很多努力。 The library is designed to match the common STL containers. 该库旨在匹配常见的STL容器。

Unless the map is huge, or you have some other way of knowing that linear search is too slow, I'd start with linear 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";
}

A variation on @Robᵩ's answer above that uses a lambda: @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";
}

(thanks to @Nawaz for his/her contribution here: https://stackoverflow.com/a/19828596/1650814 ) (感谢@Nawaz在这里的贡献: https ://stackoverflow.com/a/19828596/1650814)

I know this is a really old question but this codeproject article ( http://www.codeproject.com/Articles/3016/An-STL-like-bidirectional-map ) is a pretty good example of a bidirectional map. 我知道这是一个非常古老的问题,但这个代码项目文章( http://www.codeproject.com/Articles/3016/An-STL-like-bidirectional-map )是一个很好的双向映射示例。

This is an example program that shows how easy it is: 这是一个示例程序,显示它是多么容易:

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

Given a std::map from keys to values, the following function will return a reverse lookup table, a std::map from values to keys. 给定从键到值的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;
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM