将贴图值交换为多重贴图

swap map values to a multimap

本文关键字:交换      更新时间:2023-10-16

我用map存储了一些键值,然后我需要按值对它们进行排序,我想使用以下方法:

#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 --- 12 ---二2---三1---4

正如我需要的那样,然而...有没有更智能、更有效的方法来获得相同的结果?它必须处理一个相当大的数据集......

感谢您抽出宝贵时间:)

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

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更快,因为它只需要一个内存分配。

你可能想要构建一个双向映射抽象(基本上你已经在使用这种技术)。如果您有任意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));
    }
};