C++ 提取向量的每个其他元素

C++ 提取向量的每个其他元素,c++,stdvector,C++,Stdvector,有没有比迭代原始向量并比较每个索引的索引%2==0更快速的方法将std::vectors拆分为两个大小为一半的std::vectors(一个包含奇数索引的值,另一个包含偶数索引的值)呢 // Make sure the vector is not empty if(!v.empty()){ for(size_t i = 0; i < (v.size() - 1); i+=2){ v1.push_back(v[i]); v2.push_back(v[i

有没有比迭代原始向量并比较每个索引的
索引%2==0
更快速的方法将
std::vectors
拆分为两个大小为一半的
std::vectors
(一个包含奇数索引的值,另一个包含偶数索引的值)呢
// Make sure the vector is not empty
if(!v.empty()){
    for(size_t i = 0; i < (v.size() - 1); i+=2){
        v1.push_back(v[i]);
        v2.push_back(v[i + 1]);
    }

    if(v.size() % 2) v1.push_back(v.back());
}
如果(!v.empty()){ 对于(大小i=0;i<(v.size()-1);i+=2){ v1.推回(v[i]); v2.推回(v[i+1]); } 如果(v.size()%2)v1.push_back(v.back()); } 如多人评论中所述,您必须检查向量是否为空。通过在循环之前调整两个向量的大小,可以避免回推调用

// Make sure the vector is not empty
if(!v.empty()){
    v1.resize((v.size() + 1) / 2);
    v2.resize(v.size() / 2);
    for(size_t i = 0, j = 0; i < (v.size() - 1); i+=2, j++){
        v1[j] = (v[i]);
        v2[j] = (v[i + 1]);
    }

    if(v.size() % 2) v1.push_back(v.back());
}
//确保向量不是空的
如果(!v.empty()){
v1.调整大小((v.大小()+1)/2);
v2.调整大小(v.size()/2);
对于(大小i=0,j=0;i<(v.size()-1);i+=2,j++){
v1[j]=(v[i]);
v2[j]=(v[i+1]);
}
如果(v.size()%2)v1.push_back(v.back());
}

我不确定“更好”是什么意思,但如果C++11可以使用:

#包括
#包括

#现在包括。

旧Q,但因为还没有人建议使用迭代器和
std::next

// assert myvec.size() % 2 == 0
const unsigned long n = myvec.size() / 2;
std::vector<T> v1(n), v2(n);
std::vector<T>::iterator it = myvec.begin(), i1 = v1.begin(), i2 = v2.begin();
while (it != myvec.end()) {
    v1[*i1] = myvec[*it];
    it = std::next(it);
    i1 = std::next(i1);
    v2[*i2] = myvec[*it];
    it = std::next(it);
    i2 = std::next(i2);
}
//断言myvec.size()%2==0
const unsigned long n=myvec.size()/2;
std::向量v1(n),v2(n);
std::vector::iterator it=myvec.begin(),i1=v1.begin(),i2=v2.begin();
while(it!=myvec.end()){
v1[*i1]=myvec[*it];
it=std::next(it);
i1=标准::下一个(i1);
v2[*i2]=myvec[*it];
it=std::next(it);
i2=标准::下一个(i2);
}

我不知道它是否有用:您是否尝试过?可以使用增量2而不是1将其分成两个过程,但几乎肯定会比您已有的
%2
版本慢。您对“更好”的定义是什么?更可读的代码?更快?要键入的代码更少?@user1504193我编辑您的问题是为了更快。请注意,向量不应为空,因为在这种情况下,循环条件将失败。我不明白这怎么比%2方式更快。。。如果push_back、i+1和操作符[]都是c的复杂度,这将类似于N/2*5c。。。由于%2在每个元素中循环,您不会有类似于N*2c的东西吗?我猜操作符[]可能比其他两个快得多,但直觉上这似乎不太可能。你能详细说明一下吗?@Moritz这种方法每次迭代都会保存一个分支和一个除法,所以我可以很容易地看到它更快。但是如前所述,如果大小为零,则初始循环将运行许多次迭代。感谢你们的评论,我调整了我的答案。您可以使用
.reserve()
,然后使用
.push_back()
,而不用担心代价高昂的重新分配。简单来说,+1,明确的解决方案,消除了循环中出现边缘情况的可能性。是否可以将输入范围重新用于其中一个输出范围?@jrok,不,这是不可能的。根据标准:输入范围不得与输出范围重叠。我想知道这是为什么。它被明确地允许用于
std::transform
// assert myvec.size() % 2 == 0
const unsigned long n = myvec.size() / 2;
std::vector<T> v1(n), v2(n);
std::vector<T>::iterator it = myvec.begin(), i1 = v1.begin(), i2 = v2.begin();
while (it != myvec.end()) {
    v1[*i1] = myvec[*it];
    it = std::next(it);
    i1 = std::next(i1);
    v2[*i2] = myvec[*it];
    it = std::next(it);
    i2 = std::next(i2);
}