创建std :: vector副本减去一个元素

时间:2016-12-03 18:43:07

标签: c++ algorithm vector data-structures time-complexity

我有一个std :: vector [1,2,3,4,5],我想得到另一个包含所有元素的向量,但是第二个:[1,3,4,5]。一种方法是(vec1是我的输入向量):

std::vector<int> vec2;
vec2 = vec1;
vec2.erase(vec2.begin()+1)

这里我不太喜欢O(n)复杂度的擦除,所以考虑到数组的副本,我将有2n个操作。我以为旧的虚拟方式会更好:

std::vector<int> vec2;
for(int i=0; i<vec1.size(); ++i){
    if (i != 1) 
        vec2.push_back(vec1[i]);
}

这是O(n)时间摊销。渐近行为是相同的,但操作次数可能更小。

我必须在相当小的矢量(大约100个元素)上做这个,但我有数十亿个。我会注意到一个显着的差异吗?

你会怎么做?

1 个答案:

答案 0 :(得分:0)

这是我能想到的最快的方式:

std::vector<int> vec1{1, 2, 3, 4, 5};

// Do not call the constructor with the known size here. That would allocate
// AND initialize a lot of data that will be overwritten later anyway.
std::vector<int> vec2;

// Instead, use it on 'reserve' since it only allocates the memory and
// leaves it uninitialized. The vector is still considered empty, but its
// underlying capacity will be big enough to be filled with new data
// without any unnecessary initializations and reallocations occuring (as long
// as you don't exceed the capacity)
vec2.reserve(vec1.size() - 1);

// Nothing expensive should be going on behind the scenes now, just fill it up
for(auto it = vec1.begin(), skip = vec1.begin() + 1 ; it != vec1.end() ; ++it) {
    if(it != skip) {
        vec2.push_back(*it);
    }
}