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

C++ 为什么在使用std::remove()从向量中删除多个值时会发生跳过?,c++,arrays,c++11,vector,C++,Arrays,C++11,Vector,我正在做一件事,前几天晚上我偶然发现了Reddit,你每天都要做一个编程挑战。它看起来真的很好,并且在我学习的过程中为我自己提供了很多练习 我遇到了一个问题,我尝试使用std::remove()从向量中删除一些内容,它删除了所需的数字,这就是问题所在,它后面的下一个数字。我尝试过其他功能和各种方法,但这似乎是最实用的,感觉非常接近我需要的 我的代码: #包括 #include即使删除了元素,也会增加索引。只有在不删除元素的情况下,才需要增加索引 请注意,您的算法需要O(N2)个时间,而实现此功能

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

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

我的代码:
#包括

#include

即使删除了元素,也会增加索引。只有在不删除元素的情况下,才需要增加索引


请注意,您的算法需要O(N2)个时间,而实现此功能的复杂性为O(N)。另外,
std::vector::at()
是一种令人讨厌的东西,最好不要使用!在最好的情况下,这只是浪费时间,在最坏的情况下,它掩盖了错误。

即使删除了元素,也会增加索引。只有在不删除元素的情况下,才需要增加索引


请注意,您的算法需要O(N2)个时间,而实现此功能的复杂性为O(N)。另外,
std::vector::at()
是一种令人讨厌的东西,最好不要使用!在最好的情况下,它只是浪费时间,在最坏的情况下,它掩盖了错误。

remove
通过const引用将要删除的对象删除,并假设它在整个删除过程中不会改变

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

使用一元
+
强制复制:

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

然后您将看到中指出的问题。也要解决这个问题。

remove
通过const引用获取要删除的对象,并假设它在整个删除过程中不会发生更改

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

使用一元
+
强制复制:

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

然后您将看到中指出的问题。也可以解决这个问题。

假设唯一的错误是递增的,
std::unique
将接受
[0,0,1,2]
并返回
[0,1,2]
。Blake的代码将返回
[1,2]
@BillLynch:是的,我实际上也注意到了这一点(我将删除关于
std::unique()
的注释)。当然,不正确的增量仍然存在,因为存在一个
O(N)
算法…@DietmarKühl我试图完全删除任何重复的内容。我应该这么说,既然有三个4,我需要完全移除它们。最后的答案应该是一个5。@BlakeBarnes00:yes-正如Bill Lynch前面提到的,
std::unique()
并不能完全满足您的需要。然而,类似于
std::unique()
-的算法仍然会产生一个O(N)算法来解决这个问题。如果向量中0-10范围内有N个(比如1000万个)随机整数,那么你的方法将花费与N²成比例的时间,(一个因子N用于扫描每个元素,另一个因子是因为删除一个元素需要向下移动它上面的所有元素。)一个更好的算法从一开始就使用两个指针/索引/迭代器向前扫描,一个作为目标,一个作为源。如果找到重复的,只需前进源。如果找到不重复的,则将源处的值移动到目标并同时前进。(如果源==dest,则跳过移动)假设唯一的bug是递增的,
std::unique
将接受
[0,0,1,2]
并返回
[0,1,2]
。Blake的代码将返回
[1,2]
@BillLynch:是的,我实际上也注意到了这一点(我将删除关于
std::unique()
的注释)当然,不正确的增量仍然存在,正如存在
O(N)的事实一样
algorithm…@DietmarKühl我正试图完全删除任何重复的内容。我应该这么说,既然有三个4,我就需要完全删除它们。最后的答案应该是5。@BlakeBarnes00:是-正如比尔·林奇所说,
std::unique()
并不能完全满足您的需要。但是,类似于
std::unique()
-的算法仍然会产生一个O(N)算法来解决这个问题。如果向量中0-10范围内有N个(比如1000万个)随机整数,那么您的方法所需的时间将与N²成比例,(一个因子N用于扫描每个元素,另一个因子是因为删除一个元素需要向下移动它上面的所有元素。)一个更好的算法从一开始就使用两个指针/索引/迭代器向前扫描,一个作为目标,一个作为源。如果找到重复的,只需前进源。如果找到不重复的,则将源处的值移动到目标并同时前进。(如果源==dest,则跳过移动)我有一个问题,使用一元+做什么?再次-这是我第一次使用向量这结束了工作!我有一个问题,使用一元+做什么?再次-这是我第一次使用向量