[英]efficient way to get key from std::map value
I have a map as below : 我有一张地图如下:
std::map< std::string ,int> mapobj;
mapobj["one"] = 1;
mapobj["two"] = 2;
mapobj["three"] =3 ;
how to get key when input is value 输入值时如何获取键
EX : EX:
input : 1 输入:1
output : one 输出:一
Note : In my case value is unique 注意:在我的情况下,值是唯一的
A one-to-one mapping is actually quite easy, the fastest way to do it is to probably maintain two maps, one for each direction. 一对一映射实际上非常简单,最快的方法是维护两个映射,每个映射一个。 It becomes more complicated if it's not one-to-one since you'll need to provide a way to get a collection of values or key, rather than a single one. 如果它不是一对一的话会变得更加复杂,因为你需要提供一种方法来获取值或键的集合 ,而不是单个的。 Happily, you only have the one-to-one requirement. 令人高兴的是,你只有一对一的要求。
One of the maps is the one you have now, the other will map the values to a given key, soboth would be: 其中一个地图是你现在拥有的地图,另一个地图将值映射到给定的密钥,soboth将是:
std::map<std::string, int> forwardmapobj;
std::map<int, std::string> reversemapobj;
and these would be maintained within a bidimap
class of some sort. 这些将保持在某种bidimap
类中。
Whenever you insert to, or delete from, your bidimap
, you have to perform the equivalent operation on both internal maps. 无论何时插入或删除bidimap
,都必须在两个内部地图上执行等效操作。
For example, here's some pseudo-code. 例如,这是一些伪代码。 It maintains the two maps and ensures that they'e kept in sync for whatever operations you have that change the keys and values: 它维护着两个映射,并确保它们与您更改键和值的任何操作保持同步:
class biDiMap:
map<string, int> forwardMap
map<int, string> reverseMap
void add(string key, int val):
if exists forwardMap[key]: throw exception 'duplicate key'
if exists reverseMap[val]: throw exception 'duplicate value'
forwardMapObj[key] = val
reverseMapObj[val] = key
void delKey(string key):
if not exists forwardMap[key]: throw exception 'no such key'
delete reverseMap[forwardMap[key]]
delete forwardMap[key]
void delVal(int val):
if not exists reverseMap[val]: throw exception 'no such value'
delete forwardMap[reverseMap[val]]
delete reverseMap[val]
int getValFor(string key): return forwardMap[key]
string getKeyFor(int val): return reverseMap[val]
Obviously, there's plenty of other stuff you could add but that should form the basis. 显然,你可以添加许多其他东西,但这应该构成基础。 In any case, you've probably got enough work ahead of you turning that into a C++ class :-) 无论如何,在你把它变成C ++类之前,你可能已经有了足够的工作:-)
If you don't want to roll your own solution, then Boost has a very good one that you can pretty well use as is. 如果你不希望推出自己的解决方案,然后升压有一个非常好的一个,你可以作为是很好用。 Boost.Bimap
provides a fully-templated bi-directional map that you should be able to use with minimal code, such as the following complete program: Boost.Bimap
提供了一个完全模板化的双向映射,您应该能够使用最少的代码,例如以下完整的程序:
#include <iostream>
#include <string>
#include <boost/bimap.hpp>
using std::string;
using std::cout;
using std::exception;
using boost::bimap;
int main()
{
typedef bimap<string, int> SiMap;
typedef SiMap::value_type SiEntry;
SiMap bidi;
bidi.insert(SiEntry("ninety-nine", 99));
int i = 0;
for (string str: {"one", "two" , "three", "four", "five", "six"}) {
bidi.insert(SiEntry(str, ++i));
}
cout << "The number of entries is " << bidi.size() << "\n\n";
for (auto i = 1; i <= 7; i += 3) {
try {
cout << "Text for number " << i << " is " << bidi.right.at(i) << "\n";
} catch (exception &e) {
cout << "Got exception looking up number " << i << ": " << e.what() << "\n";
}
}
cout << "\n";
for (auto str: {"five", "ninety-nine", "zero"}) {
try {
cout << "Number for text '" << str << "' is " << bidi.left.at(str) << "\n";
} catch (exception &e) {
cout << "Got exception looking up text '" << str << "': " << e.what() << "\n";
}
}
cout << "\n";
return 0;
}
It creates a bi-directional mapping between the textual form of a number and the integral value, then does a few lookups (in both directions) to show that it works: 它在数字的文本形式和积分值之间创建双向映射,然后进行一些查找(在两个方向上)以显示它的工作原理:
The number of entries is 7
Text for number 1 is one
Text for number 4 is four
Got exception looking up number 7: bimap<>: invalid key
Number for text 'five' is 5
Number for text 'ninety-nine' is 99
Got exception looking up text 'zero': bimap<>: invalid key
how to get key when input is value 输入值时如何获取键
First, there is no guarantee that value is unique. 首先,不能保证价值是唯一的。 I realize that you are saying it is unique. 我意识到你说它是独一无二的。 Still, conceptually speaking, this is something to keep in mind when looking at the problem. 不过,从概念上讲,在查看问题时要记住这一点。
Second, std::map
is not sorted by value. 其次, std::map
没有按值排序。 Hence, the most efficient algorithm to look for a value will be O(N)
on an average. 因此,寻找值的最有效算法平均为O(N)
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.