在c++中从向量中删除偶数

cclgggtu  于 2022-12-24  发布在  其他
关注(0)|答案(5)|浏览(186)

有人能帮我实现这个功能吗:假设我需要使用reference从向量中删除所有偶数:我可以这样做吗?push_back是正确的还是我应该使用其他方法?

void evenRemoe(vector<int>& arr) {
    for(int i = 0; i < arr.size(); i++) {
        if(arr[i] % 2 != 0) {
            push_back(arr[i]);
        }  
    }
}
bjp0bcyl

bjp0bcyl1#

使用push_back * 会添加 * 元素,所以这是行不通的。
您可以将std::erase_if与函子(如lambda或其他充当一元 predicate 的函数)一起使用,以决定应该删除哪些元素。

void evenRemoe(std::vector<int>& arr) {
    std::erase_if(arr, [](int i) { return i % 2 == 0; });
}

在C++20之前,您可以实现擦除-删除习惯用法

#include <algorithm>
void evenRemoe(std::vector<int>& arr) {
    arr.erase(std::remove_if(arr.begin(), arr.end(),
                             [](int i) { return i % 2 == 0; }),
              arr.end());
}
polhcujo

polhcujo2#

push_backstd::vector的一个方法,用于将一个元素 * append * 到向量的末尾,而不是 * remove *。您需要的是erase方法之一。
但是,在删除要迭代的向量元素时要小心,必须注意在删除元素时避免索引递增。
更好的方法是使用std::remove_if算法,而不是自己迭代向量。

void evenRemove(vector<int>& arr) {
    auto it = std::remove_if(arr.begin(), arr.end(),
        [](int n) { return (n % 2) == 0; });
    arr.erase(it, arr.end());
}

尽管名称如此,std::remove_if实际上并没有从向量中“移除”任何元素,而是移动与 predicate 匹配的元素(在我们的例子中--所有偶数)到向量的末尾,并返回一个指向第一个这样的元素的迭代器。因此,要真正删除元素,需要调用erase,迭代器表示包含偶数的向量尾部。

yfjy0ee7

yfjy0ee73#

不,push_back()不是正确的用法。它是用来 * 添加 * 值的,而不是用来 * 删除 * 值的。
此外,代码实际上查找的是 odd 值,而不是 even 值。
您可以使用std::vector::erase()删除单个值,例如:

void evenRemoe(vector<int>& arr){
    for(size_t i = 0; i < arr.size();){
        if (arr[i] % 2 == 0){
            arr.erase(arr.begin()+i);
        }else{
            ++i;
        }
    }
}

或者,考虑通过std::remove_if()std::vector::erase()使用Erase-Remove idiom,例如:

#include <algorithm>

void evenRemoe(vector<int>& arr){
    arr.erase(
        std::remove_if(arr.begin(), arr.end(),
            [](int value){ return (value % 2) == 0; }
        ),
        arr.end()
    );
}

或者,在C++20中,通过std::erase_if(),例如:

void evenRemoe(vector<int>& arr){
    std::erase_if(arr,
        [](int value){ return (value % 2) == 0; }
    );
}
pftdvrlh

pftdvrlh4#

从C20开始你可以使用std::erase_if(),在C20之前,擦除-移除习惯用法曾经是这个问题的解决方案。

v.erase(std::remove_if(v.begin(), v.end(), is_even), v.end());

其中is_even是函子

d6kp6zgx

d6kp6zgx5#

使用迭代器从向量中删除多个元素。注意当我们使用迭代器删除时,它会失效。

int main(){
        vector<int> vec={1,2,3,4,5,6,7,8,9};
        for(auto it=vec.begin();it!=vec.end();){
           if(*it%2==0)
               vec.erase(it);
           else
               it++;
        }
        for(auto i:vec){
            cout<<i<<" ";
        }
        return 0;
    }

输出:1 3 5 7 9
第2种方法

int main(){
    vector<int> vec={1,2,3,4,5,6,7,8,9};
    vec.erase(remove_if(vec.begin(),vec.end(),[](int i){
        return i%2==0;
    }),vec.end());

    for(auto i:vec)
        cout<<i<<" ";
    
    return 0;
}

相关问题