问题描述
考虑以下向量:
std::vector<int> arr = {20, 37,11,20,15}
我需要删除重复项,即遇到超过 n
次(在本例中为 n=1
)
结果向量应如下所示:
{20,37,15}
即应该删除后面的元素,而不是前面的元素。
我有一个想法,在 std::remove_if 函数中使用 rbegin() 和 rend() 迭代器来开始从末尾删除元素,但是我不确定如何在 remove_if 之后从向量中删除元素完毕。我相信“剩饭剩菜”是一开始就积累起来的:
auto new_end = std::remove_if(arr.rbegin(),arr.rend(),[&n,&arr](const int a) {
return std::count(arr.begin(),arr.end(),a) > n;
});
//how to erase garbage?
解决方法
传递给 std::remove_if 的函子可以有内存。
使用函子的代码
Product
使用 lambda 的代码
struct remove_duplicates {
std::map<int,int> seen_values_;
bool operator()(int x) {
seen_values_[x]++;
return seen_values_[x] > 1;
}
};
int main() {
std::vector<int> arr = {20,37,11,20,15};
arr.erase(
std::remove_if(arr.begin(),arr.end(),remove_duplicates()),arr.end());
for (int x : arr)
std::cout << x << " ";
std::cout << std::endl;
}
两者的输出相同
int main() {
std::vector<int> arr = {20,15};
std::map<int,int> seen_values;
arr.erase(
std::remove_if(
arr.begin(),[&seen_values](int x) {
seen_values[x]++;
return seen_values[x] > 1;
}),arr.end());
for (int x : arr)
std::cout << x << " ";
std::cout << std::endl;
}
关于 std::remove_if 的注释
“剩下的垃圾”实际上是在最后。 20 37 11 15
返回一个迭代器到第一个位置开始删除。