C++ 将 vector 中的所有元素复制到 map / unordered_map 中的最佳方法

C++ best way to copy all elements from vector into map / unordered_map

使用 C++,如果我想将 vector 转换为 setunordered_set 容器,可以通过以下方式轻松完成:

#include <iostream>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using namespace std;

int main() {
    vector<int> vec {1, 2, 2, 3, 3, 3, 4, 4, 4, 4};

    // pass
    unordered_set<int> uSet(vec.begin(), vec.end());
    // pass
    set<int> s(vec.begin(), vec.end());
    // fail
    unordered_map<int, size_t> uMap(vec.begin(), vec.end());
    // fail
    map<int, size_t> m(vec.begin(), vec.end());

    return 0;
}

但是,相同的技术不适用于 mapunordered_map 容器。我想知道是否有更好的方法将矢量中的所有元素存储到 map / unordered_map 容器中,而不是:

for (int ele : vec) {
    ++uMap[ele];
}

此外,下面的代码调用了 https://en.cppreference.com/w/cpp/container/unordered_set/unordered_set 中的哪个复制构造函数:

set<int> s(vec.begin(), vec.end()); 

为什么 https://en.cppreference.com/w/cpp/container/unordered_map/unordered_map 中的类似复制构造函数不可用?

一个map条目有两个"values",而一个vector只有一个。 如果要将矢量元素插入到地图中,则需要决定使用哪个 值将成为键,而哪些将成为值。 这样做的方法是使用成对向量 (vector < pair < K , V >>),它可以像您之前所做的那样用于初始化地图。

让我们看看你的set构造。

vector<int> vec {1, 2, 2, 3, 3, 3, 4, 4, 4, 4};

set<int> s(vec.begin(), vec.end());

这会成功,因为您的 setvalue_typeint。这不仅仅是方便的术语。一个std::set定义了一个member typevalue_type,我是说std::set<int>::value_typeint。由于取消引用 vec.begin() 给出了一个可隐式转换为 int 的值(嗯,它 int),此构造成功。

转到 map,还有一个名为 value_typemember type。不过这一次,value_type 不是 int,因此您提出的构造失败了。 mapvalue_type 是包含键值对的 pair。也就是说,std::map<int, size_t>::value_typestd::pair<const int, size_t>。由于没有已知的从 int 到任何形式的 std::pair 的转换,您提出的构造失败。

如果您改为从 pairvector 开始工作,您的构建可能会成功。

vector<pair<const int, size_t>> vecp { {1, 2}, {2, 3}, {3, 3}, {4, 4}, {4, 4} };

map<int, size_t> m(vecp.begin(), vecp.end());

这导致 m[1] == 2m[2] == 3m[3] == 3m[4] == 4。多余的 {4,4} 被删除,因为这是 map,而不是 multimap。 (未指定第一个还是第二个 {4,4} 被丢弃,但丢弃的是额外的那个。)