为什么在使用std :: remove()从向量中删除多个值时会发生跳过?

时间:2017-01-04 06:20:09

标签: c++ arrays c++11 vector

我正在做challenge我偶然发现了Reddit,那天晚上你每天都要做一次编程挑战。看起来真的很好,并且在我学习的过程中为自己提供了很多练习。

我遇到了这个问题,我尝试使用std::remove()从矢量中移除某些内容并删除所需的数字,这就是问题,它之后的下一个数字。我尝试过做其他功能和各种方法,但这看起来最实用,感觉非常接近我的需要。

我的代码:

#include <iostream>
#include <algorithm>  // std::sort(), std::remove()
#include <vector>


void print_array(std::vector<int> array)
{
  std::cout << "Array: ";
  for(int i = 0; i < array.size(); i++)
  {
    std::cout << array.at(i) << " ";
  }
  std::cout << std::endl;
}

int main()
{
  std::vector<int> num_array = {2, 3, 4, 2, 3, 5, 4, 6, 4, 6, 9, 10, 9, 8, 7, 8, 10, 7};

  // Sort ant then print the array.
  std::sort(num_array.begin(), num_array.end());
  print_array(num_array);

  for(int i = 0; i < num_array.size(); i++)
  {
    if(num_array.at(i) == num_array.at(i + 1))
    {
      std::cout << num_array.at(i) << " is duped\n";
      num_array.erase(std::remove(num_array.begin(), num_array.end(), num_array.at(i)), num_array.end());
      print_array(num_array);
    }
    else
    {
      std::cout << num_array.at(i) << " is not duped.\n";
    }
  }


  print_array(num_array);
  return 0;
}

输出

output image

2 个答案:

答案 0 :(得分:2)

即使刚删除元素,也会增加索引。如果没有删除元素,您只想增加索引。

请注意,您的算法需要 O(N 2 时间,而 O(N)复杂度可以实现此功能。此外,std::vector<T>::at()是一种可憎的,最好不要使用!在最好的情况下,这只是浪费时间,在最坏的情况下,它会掩盖错误。

答案 1 :(得分:1)

remove通过const引用删除该东西,并假设它在整个删除过程中不会发生变化。

您的代码违反了该假设。例如,在第一次迭代中,您通过引用num_array[0]传递remove,但该元素很快被后面的元素(值3)覆盖,然后是所有后续比较搞砸了,因为他们最终使用了新值。

强制使用一元+

复制
num_array.erase(std::remove(num_array.begin(), num_array.end(), +num_array[i]),
                num_array.end());

然后你会看到Dietmar Kühl's answer中指出的问题。修复它。