std :: vector :: reserve(unknown m),我知道m&lt; <n(通常)=“”和=“”know =“”n =“”

时间:2017-02-12 07:25:30

标签: c++ arrays c++11 data-structures

=“”

我的代码适用于m个对象,然后根据某些自定义条件仅返回某些 ' '索引的结果。

以下是一个可靠的示例(查询字符串str上的所有 std::vector<int> reports; //will keep index of ' ' in "str" for(int i=0;i<N;i++){ // str.size() = "N" bool condition = str.at(i)==' '; //"str" is string #B if(condition){ //rarely true reports.push_back(i); } } //now reports.size() = m 个字符): -

m

在这些区块中,我知道N始终小于或等于m << N通常 //int "N" is a local variable, it is not a constant. std::vector<Input> inputs; std::vector<Report> reports; //"Report" is any type of result, actually int outOfLoopVariable=0; for(int i=0;i<N;i++){ bool condition = some logic #B about "inputs[i]" and "outOfLoopVariable"; outOfLoopVariable= ....; //some complex logic #B int var1 = ....; //some complex logic #B //var2, var3, etc. if(condition){ //rarely true reports.push_back(Report(i,var1,var2,...)); } }

在现实生活中,块更复杂,但共享类似的算法: -

#B

原始问题

算法O(N)的总复杂度= std::vector::push_back
O(m*log(m))的总复杂度=

    在大多数情况下
  • m<<NO(N*log(N))时)
  • 在最糟糕的情况下(当m~N)时,
  • #B

oLen 所述,这是完全错误的。 但是,我决定保留它作为参考。

问题

修改)算法vector需要多次重新分配vector

问题

如何使上述块的复杂度为O(N)?
修改,感谢 oLen )如何避免对reports.reserve(N)(1-&gt; 2-&gt; 4-&gt; ...)进行不必要的内部预留?

我糟糕的解决方案

多年来,我一直通过以下方法解决这个问题: -

  1. report在第一次发言时 - 在大多数情况下这是一种过度保留 当N是一个大对象并且m非常大(有问题,10000 +)时,这真的很糟糕。
  2. 循环2次。
    • 第一个循环确定reserve(m)
    • 然后reports.push_back(i);
    • 最后,第二个循环执行实际的lambda[&]
    • 不方便。代码重复往往会导致较小的可维护性问题 (可以通过#B部分解决,稍微牺牲可读性)
    • 此外,粗略地说,O(2*n)的复杂性现在是O(1.x*n)
    • ...或replication: replSetName:rs0 oplogSizeMB:100 master:true 如果我可以省略第一个循环的某些计算。
  3. 我希望有更好的方法。

2 个答案:

答案 0 :(得分:1)

答案:只是不要更改您的代码,也不要使用reserve

std::vector::push_back的复杂性是不变的(考虑amortized time),所以只要使用它就可以了。

答案 1 :(得分:1)

有第三种方法:使用链接列表report。没有过度预订。没有额外的循环。

但可能会慢一些。