有没有更惯用的方法来拆分 std::vector?
Posted
技术标签:
【中文标题】有没有更惯用的方法来拆分 std::vector?【英文标题】:Is there a more idiomatic way to split a std::vector? 【发布时间】:2015-01-31 07:48:40 【问题描述】:我编写了一个函数,可以将大小为 N 的向量拆分成大小不超过 M 的块。
所以给定一个大小为 47 的向量,块大小为 10,我们得到 5 个大小的块:10,10,10,10,7。
template<typename T> std::vector<std::vector<T>> chunkVector(typename std::vector<T> source, typename std::vector<T>::size_type chunkSize)
typename std::vector<std::vector<T>> returnVector;
for (typename std::vector<T>::size_type i = 0; i < source.size(); i += chunkSize)
typename std::vector<T>::iterator start = source.begin() + i;
typename std::vector<T>::iterator end = start + chunkSize > source.end() ? source.end() : start + chunkSize;
typename std::vector<T> tempVector(start, end);
returnVector.push_back(tempVector);
return returnVector;
有没有更惯用的方法来做到这一点? random_access 迭代器的要求向我表明可能有更好的方法。
【问题讨论】:
你应该通过 const 引用传递第一个参数。 其实@PaulMcKenzie,如果你担心性能问题,他最好只对整个类型进行模板,而不是std::vector<T>
,然后使用完美转发。
@JohnCarter,这个解决方案看起来或多或少没问题。我无法立即想到任何更好的解决方案。我想我会建议让 ?:
运算符更详细(拆分成一个真正的 if 语句),这样它会更清晰一些。
里面有几个多余的typename
s。
【参考方案1】:
我唯一不同的是如何迭代,以及我们如何附加到结果向量上:
template<typename T>
std::vector<std::vector<T>> chunkVector(const std::vector<T>& source, size_t chunkSize)
std::vector<std::vector<T>> result;
result.reserve((source.size() + chunkSize - 1) / chunkSize);
auto start = source.begin();
auto end = source.end();
while (start != end)
auto next = std::distance(start, end) >= chunkSize
? start + chunkSize
: end;
result.emplace_back(start, next);
start = next;
return result;
【讨论】:
我要加result.reserve(source.size() / chunkSize+1);
@JonathanWakely 是的,完成了。除了表达方式略有不同。
不错的 C++11 方法。我也总是忘记 std::distance 。以上是关于有没有更惯用的方法来拆分 std::vector?的主要内容,如果未能解决你的问题,请参考以下文章
是否有更惯用的方法来更新 ActiveRecord 属性哈希值?