C++ 给定从键到索引的映射,将值(映射的_类型)从映射复制到向量
假设我们有一个函数C++ 给定从键到索引的映射,将值(映射的_类型)从映射复制到向量,c++,algorithm,c++11,stl,c++14,C++,Algorithm,C++11,Stl,C++14,假设我们有一个函数key\u to\u index,它将映射的键映射到向量的索引。举个例子,让我们把它简单化: std::map<int, int> source = {{1,55}, {4, 20}, {6, 25}}; std::vector<int> target; int key_to_index(int key) {return key;} 基本上,您可以创建一个新的映射,该映射使用转换的键存储相同的值: std::map<int, int> t
key\u to\u index
,它将映射的键映射到向量的索引。举个例子,让我们把它简单化:
std::map<int, int> source = {{1,55}, {4, 20}, {6, 25}};
std::vector<int> target;
int key_to_index(int key) {return key;}
基本上,您可以创建一个新的映射,该映射使用转换的键存储相同的值:
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::map转换;
std::transform(std::cbegin(源代码),std::cend(源代码),
插入器(已转换,已转换.end()),
[](const auto&e){
返回std::make_pair(键到索引(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;
}
);
std::向量目标;
target.resize(transformed.rbegin()->first+1);
std::for_each(std::cbegin(转换)、std::cend(转换),
[&目标](常数自动和e){
目标[e.first]=e.second;
}
);
无论如何,我相信最初的版本更好。STL并不总是使代码更高效,甚至更可读。基本上,您可以创建一个新的映射,用转换的键存储相同的值:
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::map转换;
std::transform(std::cbegin(源代码),std::cend(源代码),
插入器(已转换,已转换.end()),
[](const auto&e){
返回std::make_pair(键到索引(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;
}
);
std::向量目标;
target.resize(transformed.rbegin()->first+1);
std::for_each(std::cbegin(转换)、std::cend(转换),
[&目标](常数自动和e){
目标[e.first]=e.second;
}
);
无论如何,我相信最初的版本更好。STL并不总是使代码更高效,甚至更可读。@Edgar的答案很好,但是,我不喜欢第二次创建地图。假设
key\u to\u index
相当快,最好只运行两次,而不是使用转换后的索引创建map
对代码的明显优化(除非键到索引
太复杂)是避免多次调整大小。然后对原始地图应用std::for_each
auto max = std::max_element(source.cbegin(), source.cend(), [](auto& lhs, auto& rhs) {
return key_to_index(lhs.first) < key_to_index(rhs.first); });
target.resize(key_to_index(max->first) + 1);
std::for_each(source.cbegin(), source.cend(), [&target](const auto& e) {
target[key_to_index(e.first)] = e.second; });
auto max=std::max\u元素(source.cbegin(),source.cend(),[](auto&lhs,auto&rhs){
返回键到索引(lhs.first)<键到索引(rhs.first);};
调整大小(键到索引(max->first)+1);
std::for_each(source.cbegin()、source.cend()、[&目标](const auto&e){
目标[key-to-index(e.first)]=e.second;});
@Edgar的答案很好,但是,我不喜欢第二次创建地图。假设key\u to\u index
相当快,最好只运行两次,而不是使用转换后的索引创建map
对代码的明显优化(除非键到索引
太复杂)是避免多次调整大小。然后对原始地图应用std::for_each
auto max = std::max_element(source.cbegin(), source.cend(), [](auto& lhs, auto& rhs) {
return key_to_index(lhs.first) < key_to_index(rhs.first); });
target.resize(key_to_index(max->first) + 1);
std::for_each(source.cbegin(), source.cend(), [&target](const auto& e) {
target[key_to_index(e.first)] = e.second; });
auto max=std::max\u元素(source.cbegin(),source.cend(),[](auto&lhs,auto&rhs){
返回键到索引(lhs.first)<键到索引(rhs.first);};
调整大小(键到索引(max->first)+1);
std::for_each(source.cbegin()、source.cend()、[&目标](const auto&e){
目标[key-to-index(e.first)]=e.second;});
您可以创建一个输出迭代器,非常类似于std::insert_迭代器
,其值类型为std::pair
和操作符=
,可以改变数组。然后,您的函数可以写成std::transform
您可以创建一个输出迭代器,非常类似于std::insert_迭代器
,其值类型为std::pair
和操作符=
,可以改变数组。那么你的函数可以写成std::transform
你的键到索引()
函数真的应该返回键而不是索引吗?@Galik OP说他把它做成了一个微不足道的身份函数,是为了减少注意力。实际实现应该无关紧要。您可以将它包装成std::transform
并使用lambda,但除此之外,我想说的是保持原样。@DeiDei您能证明一下吗?是您的键到索引()
函数真的应该返回键,而不是索引
?@Galik OP确实说过,为了降低注意力,他将其设置为微不足道的身份函数。实际的实现应该无关紧要。您可以将它包装成std::transform
并使用lambda,但除此之外,我会说保持原样。@DeiDei您能证明一下吗?我希望它会比原始代码短。。。而且我绝对不希望使用STL的版本比原始版本效率更低。@AlwaysLearning有时最好避免使用STL:)@EdgarRokyan亵渎神明的评论!竖起大拇指!我希望它会比原来的代码短。。。而且我绝对不希望使用STL的版本比原始版本效率更低。@AlwaysLearning有时最好避免使用STL:)@EdgarRokyan亵渎神明的评论!竖起大拇指!“我不喜欢第二次创建地图”。是的,我也不喜欢。刚刚发布了我脑海中浮现的第一个版本。总之,+1:)不错!这看起来确实比原始版本快。它还避免了循环中的条件“我不喜欢第二次创建贴图”。是的,我也不喜欢。刚刚发布了我脑海中浮现的第一个版本。总之,+1:)不错!这看起来确实比原始版本快。它还避免了循环内部的条件。好主意,尽管我不会那么努力地重新编写四行代码。好主意,尽管我不会那么努力地重新编写四行代码。