在给定从键到索引的映射的情况下,将值(mapped_type)从映射复制到向量

时间:2017-01-15 07:27:31

标签: c++ algorithm c++11 stl c++14

假设我们有一个函数key_to_index,它将映射的键映射到向量的索引。举个例子,让我们把它变得微不足道:

std::map<int, int> source = {{1,55}, {4, 20}, {6, 25}};
std::vector<int> target;

int key_to_index(int key) {return key;}

使用STL算法的以下循环版本是什么?

for (const auto &el: source) {
    int index = key_to_index(el.first);
    if (index > (int)target.size() - 1) target.resize(index + 1);
    target[index] = el.second;
}

3 个答案:

答案 0 :(得分:3)

@Edgar答案很好,但是,我不喜欢第二张地图创作。假设(define reduce (λ (f init ls) (if (empty? ls) init (reduce f (f init (first ls)) (rest ls))))) 速度相当快,最好只运行两次,而不是使用转换后的索引创建地图。

明显的代码优化(除非key_to_index过于复杂)是为了避免多次调整大小。然后将key_to_index应用于原始地图

std::for_each

答案 1 :(得分:1)

基本上你可以使用转换后的密钥创建一个新的 map 存储相同的值:

std::map<int, int> transformed;

std::transform(std::cbegin(source), std::cend(source),
        std::inserter(transformed, transformed.end()),
        [](const auto& e) {
            return std::make_pair(key_to_index(e.first), e.second);
        }
);

然后填写目标:

std::vector<int> target;
target.resize(transformed.rbegin()->first + 1);

std::for_each(std::cbegin(transformed), std::cend(transformed),
        [&target](const auto& e) {
            target[e.first] = e.second;
        }
);

wandbox example

无论如何,我相信初始版本更好。 STL并不总能使您的代码更高效或更易读。

答案 2 :(得分:1)

您可以创建一个与std::insert_iterator非常相似的输出迭代器,其值类型为std::pair<int,int>operator=,可以改变您的数组。然后您的函数可以写成std::transform