有人能帮我实现这个功能吗:假设我需要使用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]); } } }
bjp0bcyl1#
使用push_back * 会添加 * 元素,所以这是行不通的。您可以将std::erase_if与函子(如lambda或其他充当一元 predicate 的函数)一起使用,以决定应该删除哪些元素。
push_back
std::erase_if
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()); }
polhcujo2#
push_back是std::vector的一个方法,用于将一个元素 * append * 到向量的末尾,而不是 * remove *。您需要的是erase方法之一。但是,在删除要迭代的向量元素时要小心,必须注意在删除元素时避免索引递增。更好的方法是使用std::remove_if算法,而不是自己迭代向量。
std::vector
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,迭代器表示包含偶数的向量尾部。
yfjy0ee73#
不,push_back()不是正确的用法。它是用来 * 添加 * 值的,而不是用来 * 删除 * 值的。此外,代码实际上查找的是 odd 值,而不是 even 值。您可以使用std::vector::erase()删除单个值,例如:
push_back()
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,例如:
std::remove_if()
#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(),例如:
std::erase_if()
void evenRemoe(vector<int>& arr){ std::erase_if(arr, [](int value){ return (value % 2) == 0; } ); }
pftdvrlh4#
从C20开始你可以使用std::erase_if(),在C20之前,擦除-移除习惯用法曾经是这个问题的解决方案。
v.erase(std::remove_if(v.begin(), v.end(), is_even), v.end());
其中is_even是函子
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; }
5条答案
按热度按时间bjp0bcyl1#
使用
push_back
* 会添加 * 元素,所以这是行不通的。您可以将
std::erase_if
与函子(如lambda或其他充当一元 predicate 的函数)一起使用,以决定应该删除哪些元素。在C++20之前,您可以实现擦除-删除习惯用法
polhcujo2#
push_back
是std::vector
的一个方法,用于将一个元素 * append * 到向量的末尾,而不是 * remove *。您需要的是erase
方法之一。但是,在删除要迭代的向量元素时要小心,必须注意在删除元素时避免索引递增。
更好的方法是使用
std::remove_if
算法,而不是自己迭代向量。尽管名称如此,
std::remove_if
实际上并没有从向量中“移除”任何元素,而是移动与 predicate 匹配的元素(在我们的例子中--所有偶数)到向量的末尾,并返回一个指向第一个这样的元素的迭代器。因此,要真正删除元素,需要调用erase
,迭代器表示包含偶数的向量尾部。yfjy0ee73#
不,
push_back()
不是正确的用法。它是用来 * 添加 * 值的,而不是用来 * 删除 * 值的。此外,代码实际上查找的是 odd 值,而不是 even 值。
您可以使用
std::vector::erase()
删除单个值,例如:或者,考虑通过
std::remove_if()
和std::vector::erase()
使用Erase-Remove idiom,例如:或者,在C++20中,通过
std::erase_if()
,例如:pftdvrlh4#
从C20开始你可以使用std::erase_if(),在C20之前,擦除-移除习惯用法曾经是这个问题的解决方案。
其中is_even是函子
d6kp6zgx5#
使用迭代器从向量中删除多个元素。注意当我们使用迭代器删除时,它会失效。
输出:1 3 5 7 9
第2种方法