在 remove_if 之后从向量中擦除,使用反向迭代器:rbegin()、rend()

erasing from vector after remove_if, with reverse iterators: rbegin(), rend()

考虑以下向量:

std::vector<int> arr = {20, 37, 11, 20, 15}

我需要删除重复项,即遇到超过 n 次(在本例中为 n=1) 生成的向量应如下所示:

{20, 37, 11, 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的函子可以有记忆

使用仿函数的代码

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;
}

使用 lambda 的代码

int main() {
  std::vector<int> arr = {20, 37, 11, 20, 15};
  std::map<int, int> seen_values;
  arr.erase(
    std::remove_if(
      arr.begin(), arr.end(), [&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;
}

两者的输出相同

20 37 11 15

关于 std::remove_if

的注释

“剩下的垃圾”居然在最后。 std::remove_if returns 指向要开始删除的第一个位置的迭代器。