将地图值交换为多图

时间:2014-12-10 16:12:18

标签: c++ containers

我用地图存储了一些键值,然后我需要按值排序,我很想用它:

#include <iostream>
#include <map>
#include <string>

int main ()
{
    std::map<std::string, int> map1;
    std::multimap<int, std::string> multimap2;

    map1.insert ( std::pair<std::string, int>( "one", 4) );
    map1.insert ( std::pair<std::string, int>( "two", 2) );
    map1.insert ( std::pair<std::string, int>( "three", 2) );
    map1.insert ( std::pair<std::string, int>( "four", 1) );

    for (auto it = map1.begin(); it != map1.end(); ){
        multimap2.insert(std::pair<int, std::string>( it->second, it->first));
        map1.erase(it++);
    }

   for (auto it = multimap2.rbegin(); it != multimap2.rend(); ++it)
   std::cout << it->first << " --- " << it->second << '\n';

   return 0;
}

给了我:

4 ---一个 2 ---两个 2 ---三 1 ---四

根据我的需要,但......有更智能,更有效的方法来获得相同的结果吗? 它必须使用足够大的数据集...

感谢您的时间:)

2 个答案:

答案 0 :(得分:5)

另一种方法是将它们转储到一个向量中,并对其进行排序:

typedef std::pair<std::string, int> pair;
std::vector<pair> v;
v.reserve(map1.size());
std::copy(map1.begin(), map1.end(), std::back_inserter(v));
std::sort(v.begin(), v.end(), 
    [](pair const & a, pair const & b) {
        return a.second < b.second;
    });

这可能比插入multimap更快,因为它只需要一次内存分配。

答案 1 :(得分:1)

您可能想要构建双向地图抽象(基本上您已经使用了这种技术)。如果您有任意get_by_key / get_by_value查询,这种类可能很有用。

template <typename K, typename V>
class bi_map
{
private:
    std::map<K, V>      key_to_value_;
    std::multimap<V, K> value_to_key_;

public:
    typedef typename std::multimap<typename V, typename K>::iterator by_value_iterator;
    typedef typename std::map<K, V>::iterator  by_key_iterator;
    const V& value(const K& key) {
        return key_to_value_[key];
    }

    std::pair<by_value_iterator, by_value_iterator> keys(const V& value) {
        return value_to_key_.equal_range(value);
    }

    void set(const K& key, const V& value) {
        by_key_iterator it = key_to_value_.find(key);
        if (key_to_value_.end() != it) {
            std::pair<by_value_iterator, by_value_iterator> it_pair = value_to_key_.equal_range(key_to_value_[key]);
            while (it_pair.first != it_pair.second)
                if (it_pair.first->first == it->second) {
                    value_to_key_.erase(it_pair.first);
                    break;
                } else ++it_pair.first;
        }
        key_to_value_[key] = value;
        value_to_key_.insert(std::make_pair(value, key));
    }
};