freeCodeCamp/guide/chinese/cplusplus/erase-remove/index.md

88 lines
2.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

---
title: Eraseremove idiom
localeTitle: 删除成语
---
## Desctiprion
如何从容器中删除元素是一个常见的C ++面试问题,如果您仔细阅读本页,您可以获得一些布朗尼点数。擦除 - 移除习语是一种C ++技术,用于从容器中消除满足特定标准的元素。但是,有可能用传统的手写循环来消除元素,但擦除 - 删除习语有几个优点。
### 对照
```cpp
// Using a hand-written loop
std::vector<int> v = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
for (auto iter = v.cbegin(); iter < v.cend(); /*iter++*/)
{
if (is_odd(*iter))
{
iter = v.erase(iter);
}
else
{
++iter;
}
}
// Using the eraseremove idiom
std::vector<int> v = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
v.erase(std::remove_if(v.begin(), v.end(), is_odd), v.end());
```
正如您所看到的,带有手写循环的代码需要更多的输入,但它也存在性能问题。每个`erase`调用必须在删除后删除所有元素,以避免集合中的“间隙”。在同一容器上多次调用`erase`产生大量移动元素的开销。
另一方面,具有擦除 - 删除习语的代码不仅更具表现力,而且更有效。首先,使用`remove_if/remove`将所有不符合删除条件的元素移动到范围的前面,保持元素的相对顺序。因此,在调用`remove_if/remove` ,单次调用`erase`会删除范围末尾的所有剩余元素。
### 例
```cpp
#include <vector> // the general-purpose vector container
#include <iostream> // cout
#include <algorithm> // remove and remove_if
bool is_odd(int i)
{
return (i % 2) != 0;
}
void print(const std::vector<int> &vec)
{
for (const auto& i : vec)
std::cout << i << ' ';
std::cout << std::endl;
}
int main()
{
// initializes a vector that holds the numbers from 1-10.
std::vector<int> v = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
print(v);
// removes all elements with the value 5
v.erase(std::remove(v.begin(), v.end(), 5), v.end());
print(v);
// removes all odd numbers
v.erase(std::remove_if(v.begin(), v.end(), is_odd), v.end());
print(v);
// removes multiples of 4 using lambda
v.erase(std::remove_if(v.begin(), v.end(), [](int n) { return (n % 4) == 0; }), v.end());
print(v);
return 0;
}
/*
Output:
1 2 3 4 5 6 7 8 9 10
1 2 3 4 6 7 8 9 10
2 4 6 8 10
2 6 10
*/
```
### 来源
“删除成语”维基百科:自由百科全书。 Wikimedia Foundation [Inc。en.wikipedia.org/wiki/Erase-remove\_idiom](https://en.wikipedia.org/wiki/Erase%E2%80%93remove_idiom)
迈耶斯斯科特2001年。有效的STL50种改进标准模板库使用的具体方法。 Addison-Wesley出版社。