假设我们有一个函数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;
}
答案 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;
}
);
无论如何,我相信初始版本更好。 STL并不总能使您的代码更高效或更易读。
答案 2 :(得分:1)
您可以创建一个与std::insert_iterator
非常相似的输出迭代器,其值类型为std::pair<int,int>
和operator=
,可以改变您的数组。然后您的函数可以写成std::transform
。