Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/146.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何将向量归零<;bool>;?_C++_Vector - Fatal编程技术网

C++ 如何将向量归零<;bool>;?

C++ 如何将向量归零<;bool>;?,c++,vector,C++,Vector,我有一个向量,我想把它归零。我需要尺寸保持不变 通常的方法是迭代所有元素并重置它们。然而,vector是一个容器,根据实现情况,每个元素只能存储一位。有没有一种方法可以利用这一点有效地清除整个事件 位集,固定长度变量,具有集功能。向量有类似的东西吗?试试看 v.assign(v.size(), false); 请查看此链接: 或以下 std::fill(v.begin(), v.end(), 0) 你真倒霉std::vector是一种专门化,它显然甚至不能保证连续内存或随机访问迭代器(甚至

我有一个
向量
,我想把它归零。我需要尺寸保持不变

通常的方法是迭代所有元素并重置它们。然而,
vector
是一个容器,根据实现情况,每个元素只能存储一位。有没有一种方法可以利用这一点有效地清除整个事件

位集
,固定长度变量,具有
功能。向量有类似的东西吗?

试试看

v.assign(v.size(), false);
请查看此链接:

或以下

std::fill(v.begin(), v.end(), 0)

你真倒霉
std::vector
是一种专门化,它显然甚至不能保证连续内存或随机访问迭代器(甚至不能保证向前?!),至少根据我对cppreference的阅读——解码标准将是下一步

因此,请编写特定于实现的代码,并使用一些标准的归零技术,或者不要使用该类型。我投3票


公认的智慧是,这是一个错误,可能会被弃用。如果可能,请使用不同的容器。绝对不要弄乱内脏,也不要依赖它的包装。检查您的
std
库中是否有动态位集,或者在
std::vector

中滚动您自己的包装器。到目前为止,在发布的答案中似乎有很多猜测,但事实很少,因此可能值得做一些测试

#include <vector>
#include <iostream>
#include <time.h>

int seed(std::vector<bool> &b) {
    srand(1);
    for (int i = 0; i < b.size(); i++)
        b[i] = ((rand() & 1) != 0);
    int count = 0;
    for (int i = 0; i < b.size(); i++)
    if (b[i])
        ++count;
    return count;
}

int main() {
    std::vector<bool> bools(1024 * 1024 * 32);

    int count1= seed(bools);
    clock_t start = clock();
    bools.assign(bools.size(), false);
    double using_assign = double(clock() - start) / CLOCKS_PER_SEC;

    int count2 = seed(bools);
    start = clock();
    for (int i = 0; i < bools.size(); i++)
        bools[i] = false;
    double using_loop = double(clock() - start) / CLOCKS_PER_SEC;

    int count3 = seed(bools);
    start = clock();
    size_t size = bools.size();
    bools.clear();
    bools.resize(size); 
    double using_clear = double(clock() - start) / CLOCKS_PER_SEC;

    int count4 = seed(bools);
    start = clock();
    std::fill(bools.begin(), bools.end(), false);
    double using_fill = double(clock() - start) / CLOCKS_PER_SEC;


    std::cout << "Time using assign: " << using_assign << "\n";
    std::cout << "Time using loop: " << using_loop << "\n";
    std::cout << "Time using clear: " << using_clear << "\n";
    std::cout << "Time using fill: " << using_fill << "\n";
    std::cout << "Ignore: " << count1 << "\t" << count2 << "\t" << count3 << "\t" << count4 << "\n";
}
因此,在VC++中,最快的方法可能是您最初认为最幼稚的方法——一个分配给每个单独项目的循环。使用g++时,结果略有不同:

Time using assign: 0.002
Time using loop: 0.08
Time using clear: 0.002
Time using fill: 0.001
Ignore: 16777216        16777216        16777216        16777216
在这里,循环是(到目前为止)最慢的方法(其他方法基本上是并列的——1毫秒的速度差实际上是不可重复的)

值得一提的是,尽管测试的这一部分在g++中显示的速度要快得多,但总体时间彼此相差不到1%(VC++为4.944秒,g++为4.915秒)。

使用
std::vector::assign
方法,该方法就是为此提供的。
如果实现是特定于
bool
,则
assign
,很可能也是适当实现的

如果您能够从
向量
切换到自定义位向量表示,那么您可以使用专门为快速清除操作设计的表示,并获得一些潜在的相当显著的加速(尽管并非没有权衡)

诀窍是使用每个位向量项的整数和单个“滚动阈值”值,该值确定哪些项的计算结果为真

然后,只需增加单个阈值即可清除位向量,而无需接触其余数据(直到阈值溢出)


可以找到关于这一点的更完整的文章和一些示例代码。

我最近遇到了这一性能问题。我没有试着在网上寻找答案,但确实发现使用g++O3(Debian 4.7.2-5)4.7.2时,将赋值与构造函数一起使用会快10倍。我发现这个问题是因为我想避免额外的
malloc
。看起来赋值和构造函数一样优化,在我的基准测试中大约是两倍

unsigned sz = v.size(); for (unsigned ii = 0; ii != sz; ++ii) v[ii] = false;
v = std::vector(sz, false); // 10x faster
v.assign(sz, false); >      // 20x faster

因此,我不会说要回避使用向量的专门化;只需非常了解位向量表示。

似乎还没有提到一个好的选项:

auto size = v.size();
v.resize(0);
v.resize(size);
STL实现者应该已经选择了最有效的归零方法,所以我们甚至不需要知道可能是哪种方法。这也适用于实向量(想想模板),而不仅仅是
std::vector
monstrosy


循环中重复使用的缓冲区(如筛子等)可能有一个微小的额外优势,您只需将大小调整为当前一轮所需的大小,而不是原始大小。

作为
std::vector
的替代方法,请查看
boost::dynamic_bitset
()。通过调用
reset()
member函数,可以将1归零(即,将每个元素设置为false)


像清除一样,比如说,
std::vector
boost::dynamic_bitset
上的
reset
也可以编译成
memset
,而使用
std::vector
可能无法做到这一点。例如,请参见std::fill(v.begin(),v.end(),0)@阿利亚拉米里:OP含蓄地提到这是一种正常的方式。而且它可能不会利用在操作中设置8位的优势。您计时了吗?很可能是标准库实现中的算法,如
std::fill
。一个好方法是不要使用
vector
,因为简单地说,它是坏的。虽然
std::vector
有不幸的问题,但添加它的最初理由正是为了解决类似的问题。“不要使用它”不是一个恰当的评论,那么,“尝试”和“可能有用”;一句话两次猜测;这不是一个高质量的答案。尤其是在C++中,这样的回答可能是不可移植的,甚至是危险的。第二个代码我不太确定。没有什么值得投反对票:)注意,assign的gcc实现实际上执行了std::fill@log0,谢谢reference@log0我不是100%确定,但在我看来,
assign
中的
std::fill
是在容器字之上,而不是在单个位之上。因此,至少对于GCC来说,这可能是一种优化的方法。Jerry的VC测试是倒退的。两个平台之间的相对差异令人惊讶。两次都只有
fill
出现在速度较快的组中。我认为这里的要点是向量不可靠。“不可靠”表示它不起作用。它在任何地方都能工作,显然,您也可以指望一个内存高效的实现。那个
auto size = v.size();
v.resize(0);
v.resize(size);