我试图搜索两个相同的元素的矢量(每个任何大小),然后删除这两个元素 .
我的实现如下:
for (int i = vec1.size() - 1; i >= 0; i--) {
for (int j = 0; j < vec2.size(); j++) {
if (vec1[i] == vec2[j]) {
vec1.erase(vec1.begin() + i);
vec2.erase(vec2.begin() + j);
}
}
}
然而,虽然这适用于大多数情况,但我遇到了一些它没有的地方 . 这是我通过这些向量迭代的方式,还是我只是这样做错了?
4 回答
尝试使用
std::set_difference
从另一个向量中减去一个向量,并在std::merge
的帮助下合并这些减法 . 但是需要对向量进行排序以使用这些函数,因此首先使用std::sort
. 代码在这里:输出是:
如果你可以排序,你可以做这样的事情:
问题是,在从
vec1
和vec2
删除元素后循环遍历vec2
时,您将继续访问vec1[i]
. 如果在删除vec1
中的最后一个元素后执行此操作,则会导致未定义的行为,因为vec1[i]
不再有效 . 在if
中添加break
语句来解决此问题 .还有一种更有效的方法(
O(n*log(n)+m*log(m)+n+m)
代替O(n*m)
代表n=vec1.size()
和m=vec2.size()
) . 它涉及对矢量进行排序 . 我会留给你弄清楚的 .实际上你根本不需要向后迭代 . 在这种情况下,您的代码可以是:
但等等......我们擦除一个元素后会发生什么?然后它之后的所有元素的索引都减少了1,所以我们将跳过下一个项目!要解决这个问题,我们可以添加这个小修改:
即使我们通过擦除来改变大小,这也会起作用,因为我们正在检查
vec2
每个循环的大小!但是如果我们最终删除了vec1
的最后一项呢?我们在vec2
期间一直在迭代,这将是你的vec1 = {2}, vec2 = {2, 2, 2}
例子中的一个问题 . 为了解决这个问题,我们可以突破内循环并重复检查vec2
.把它们放在一起(并将你的下标操作符更改为
.at()
调用,这样我们就可以进行边界检查),你得到:(见此处的行动:ideone)