首页 > 解决方案 > 删除两个向量C++中的相似元素

问题描述

我正在尝试在两个向量(每个向量的任何大小)中搜索相同的元素,然后删除这两个元素。

我的实现如下:

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

然而,虽然这适用于大多数情况,但我遇到了一些不适用的情况。是我迭代这些向量的方式,还是我只是把这一切都错了?

标签: c++loopsvector

解决方案


您实际上根本不需要向后迭代。在这种情况下,您的代码可以是:

for (int i = 0; i < vec1.size(); i++) {
     for (int j = 0; j < vec2.size(); j++) {
          if (vec1[i] == vec2[j]) {
             vec1.erase(vec1.begin() + i);
             vec2.erase(vec2.begin() + j);
          }
     }
}

但是等一下……我们删除一个元素后会发生什么?然后它之后的所有元素的索引都减1,所以我们将跳过下一项!为了解决这个问题,我们可以添加这个小修改:

             vec1.erase(vec1.begin() + i--);
             vec2.erase(vec2.begin() + j--);
                                       ^^^^

即使我们通过擦除来改变大小,这也会起作用,因为我们正在检查vec2每个循环的大小!但是如果我们最终删除了 的最后一项vec1呢?在我们一直迭代之前,我们不会再次比较它的大小,这在您的示例vec2中将是一个问题。vec1 = {2}, vec2 = {2, 2, 2}为了解决这个问题,我们可以跳出内部循环并重复检查vec2.

将它们放在一起(并将您的下标运算符更改为.at()调用,以便我们进行边界检查),您将获得:

for (int i = 0; i < vec1.size(); i++) {
     for (int j = 0; j < vec2.size(); j++) {
          if (vec1.at(i) == vec2.at(j)) {
             vec1.erase(vec1.begin() + i--);
             vec2.erase(vec2.begin() + j--);
             break;
          }
     }
}

(在这里查看实际操作:ideone


推荐阅读