在地图中如何将相同值的键收集到矢量中?

时间:2014-10-20 03:46:04

标签: c++

我想在地图中收集相同值的键。使用矢量最简单的方法是什么?这意味着可以在向量中收集具有相同值的所有键。

3 个答案:

答案 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并创建一个命名类型,使代码更易于阅读。在上面的代码中,所有firstsecond的含义并不明显......

另一种替代方案,可能更有效(测量和分析)将使用变换来创建一个向量,其中元素被交换,然后迭代该向量提取感兴趣的值。

答案 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_ifstd::for_each算法的语句范围替换为lambda表达式。但在我对这个简单任务的意见中,最好使用基于语句的范围。

答案 2 :(得分:0)

在创建map的位置,请考虑使用原始unordered_multimap交换的密钥和值创建map