给出以下示例
#include <iostream>
#include <vector>
#include <algorithm>
#include<iterator>
using namespace std;
template<typename T>
ostream& operator<<(ostream& os, const vector<T>& v){
copy(v.begin(), v.end(), ostream_iterator<T>(os, " "));
return os;
}
int main (){
vector<int>vec;
vector<vector<int>> x(10,vector<int>());
for(int i=0; i< x.size(); i++)
x[i].resize((rand() % 100 + 1), 10);
for(int i=0; i< x.size(); i++)
fill(x[i].begin(),x[i].end(),0);
return 0;
}
将第二个向量中的值设置为0
的最快方法是什么日Thnx
答案 0 :(得分:5)
完全没必要用零填充内部std::vector
,因为resize
默认 - 将新元素插入到值初始化它们的向量中。在int
s的情况下,值初始化意味着将它们设置为0.
从标准中确定这一点可能有点困难,所以这里的路径(来自N4296 - C ++ 14草案):
从resize
:
如果
size() < sz
,请将sz - size()
默认插入的元素附加到序列中。
default-inserted
的定义:
进行初始化,则默认插入
X
的元素如果通过评估表达式allocator_traits<A>::construct(m, p)
其中
p
是X
内分配的元素的未初始化存储的地址[和m
是A
类型的分配器。
allocator_traits<A>::construct
的定义:
template <class T, class... Args> static void construct(Alloc& a, T* p, Args&&... args);
效果:如果调用格式良好,则调用
a.construct(p, std::forward<Args>(args)...)
;否则,[...]。
从分配器的定义:
a.construct(c, args)
效果:构造一个对象 在c
处键入C.默认值:
::new ((void*)c) C(forward<Args>(args)...)
从new
- 表达式的定义:
如果省略new-initializer,[...]
否则,新的初始化程序将根据8.5的初始化规则进行解释,以进行直接初始化。
从直接初始化的定义:
[...]
如果初始值设定项为(),则对象进行值初始化。
[..]
值初始化:
- 如果T是[...];
的(可能是cv认证的)类类型- 如果T是[...];
的(可能是cv认证的)类类型- 如果T是数组类型,那么[...];
- 否则,该对象为零初始化。
零初始化:
如果T是标量类型(3.9),则将对象初始化为通过将整数0(零)转换为T获得的值;
如果[...]
答案 1 :(得分:1)
在您的示例中,最初使用零初始化向量是最简单和最快速的。在父矢量的构造函数中,如果它们的长度相同,或者在调整大小时,如果矢量是随机长度。
如果你有一个带有旧值的向量的现有向量,并且你想将它们全部设置为零,那么memset
通常是最快的方法。由于向量保证具有连续存储,并且内部向量不包含复杂(非POD)对象,因此使用memset
for(auto& v : x)
std::memset(&v[0], 0, sizeof(v[0]) * v.size());
也就是说,std::fill_n
或std::fill
可能可能同样快,并且不仅限于POD /内置对象,而且更易于阅读,因此我建议使用它。如果您遇到瓶颈,请查看您的代码,看看您是否在目标平台上获得了memset
的任何内容。否则,坚持你所拥有的。
答案 2 :(得分:1)
在C ++ 11中
for (auto &i : x)
std::fill(i.begin(), i.end(), 0);
或(在C ++ 11之前)
for (std::vector<int>::iterator i=x.begin(), end = x.end(); i != end; ++i)
std::fill(i.begin(), i.end(), 0);
将难以击败 - 并且可能会使用索引击败循环(如x[i]
中所示)。
答案 3 :(得分:0)
使用接受初始值的vector :: vector(count,value)构造函数。在下面的例子中,它将被设置为零。
vector< vector<int> > yourVector(value1, vector<int>(value2));
// initial value will be zero