我想在地图中收集相同值的键。使用矢量最简单的方法是什么?这意味着可以在向量中收集具有相同值的所有键。
答案 0 :(得分:3)
您必须对整个容器进行线性搜索,即O(N)。
std::vector<Value> values;
std::for_each(map.begin(), map.end(),
[&](std::map<Key,Value>::value_type const & x) {
if (x.second == value)
values.push_back(x.first);
});
如果要提取值不唯一的所有键,代码的复杂性会更高,并且您需要其他数据,但您可以执行以下操作:
std::map<Value, std::pair<Key, bool>> tracker;
// Maps a 'Value' to the first 'Key' that had it, and a 'bool'
// identifying if it has already been inserted into the vector.
std::vector<Key> keys;
for_each(m.begin(), m.end(),
[](std::map<Key, Value>::value_type const& x) {
auto r = tracker.insert(std::make_pair(x.second,
std::make_pair(x.first, false));
if (!r.second) {
// Not the first time we saw this value
if (!r.first->second) {
// First key not already inserted, insert now and update flag
keys.push_back(r.first);
r.first->second = true;
}
keys.push_back(x.first);
}
});
虽然在实际代码中我会避免使用std::pair
并创建一个命名类型,使代码更易于阅读。在上面的代码中,所有first
和second
的含义并不明显......
另一种替代方案,可能更有效(测量和分析)将使用变换来创建一个向量,其中元素被交换,然后迭代该向量提取感兴趣的值。
答案 1 :(得分:1)
您可以通过以下方式执行此操作
#include <iostream>
#include <vector>
#include <string>
#include <map>
int main()
{
std::map<int, std::string> m
{
{ 1, "Monday" }, { 2, "Tuesday" }, { 9, "Monday" }
};
std::vector<int> v;
size_t n = 0;
std::string s( "Monday" );
for ( const auto &p : m )
{
if ( p.second == s ) ++n;
}
v.reserve( n );
for ( const auto &p : m )
{
if ( p.second == s ) v.push_back( p.first );
}
for ( const auto &x : v ) std::cout << x << ' ';
std::cout << std::endl;
return 0;
}
输出
1 9
您可以将相应std::count_if
和std::for_each
算法的语句范围替换为lambda表达式。但在我对这个简单任务的意见中,最好使用基于语句的范围。
答案 2 :(得分:0)
在创建map
的位置,请考虑使用原始unordered_multimap
交换的密钥和值创建map
。