【问题标题】:Removing the only element of a vector during iteration?在迭代期间删除向量的唯一元素?
【发布时间】:2019-05-09 15:34:40
【问题描述】:

我对迭代器有点困惑。我想删除一个恰好具有特定值的向量成员,即使它是向量中的唯一元素。

我有一个类的向量。我想做的是当类成员的变量之一(例如width)具有某个值时,该类实例将从向量中永久删除。让我们假设该类仅由一个构造函数构成,将 widthheight 这两个公共变量和一个析构函数作为其公共函数。

vector<Rectangle> vect1;

Rectangle memVar1(3, 5);
Rectangle memVar2(6, 10);

vect1.push_back(memVar1);
vect1.push_back(memVar2);

所以它将遍历向量的所有成员,搜索高度是否为 5。

for(std::vector<myClass>::iterator it = vect1.begin(); it != vect1.end(); ++it) {
    if (it->height == 5) {
    //delete the element from the vector, and so memVar2 will be the only element and it will be in slot 0 of the vector now.
    it = vect1.erase(it);
    } 
}

这按预期工作,如果向量中只有一个元素,恰好有不需要的高度 5,就会出现问题。我想从向量中删除该元素,但也可以安全地退出迭代.在上面的例子中,我可以在将break 设置为 vect1.erase(it) 之后输入它,但如果我的擦除位于迭代循环内的开关内,这将不起作用,因此我需要一个条件变量,当它离开 switch 语句时从那里退出。

所以我想知道是否有一种方法不需要我使用break,以防止在我在 switch 语句中擦除时出现混乱的代码?

【问题讨论】:

  • @Swordfish 我忘了提而不是在循环头中增加它
  • @molbdnilo:这基本上就是答案 - 您跳过一个元素,当删除向量的最后一个(或唯一一个)元素时,该元素不存在。
  • 你已经接受了我的回答,虽然我觉得我的解释不太准确。请参阅答案编辑以更好地解释代码中的错误
  • 请注意,如果需要删除太多元素,您将获得 O(n^2) 复杂度。只需创建一个新向量即可获得 O(n) 复杂度

标签: c++ c++98


【解决方案1】:

在循环中删除元素时,您必须考虑当您删除索引i 处的元素时,下一个元素位于索引i,而不是索引i+1。同样擦除向量中的元素会使您擦除的位置处和之后的所有迭代器无效(实际上您已经考虑到了这一点)。因此循环应该看起来像:

for(auto it = vect1.begin(); it != vect1.end(); /* no increment here */) {
    if (it->height == 5) {
        it = vect1.erase(it);
    } else {
        ++it;
    }
}

PS:写完答案后,我才意识到我的解释是假的。正确的解释是erase 确实已经在你删除的那个元素之后返回了一个迭代器,所以你不应该增加它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-29
    • 2017-10-24
    • 1970-01-01
    • 1970-01-01
    • 2015-04-21
    • 1970-01-01
    • 2016-04-15
    相关资源
    最近更新 更多