【问题标题】:c++ vector; remove_if only removing a single value?c++向量; remove_if 只删除一个值?
【发布时间】:2011-10-11 17:33:52
【问题描述】:

我应该实现一个从容器中删除一系列值的函数。所以

eraseRange(v, 1.5, 24);

例如,将从容器 v 中删除任何大于 1.5 且小于 24 的值。我的函数非常适用于我使用的列表:

container.erase(remove_if(container.begin(), container.end(), rg));

其中 rg 检查它是否在范围内(该部分的实现不是问题,所以我不打算详细说明)。

但是,当为向量调用 eraseRange 并使用类似的方法擦除值时,只会擦除第一个值。因此,如果我有一个数字从 1 到 10 的向量,我会调用:

eraseRange(v, 3, 7);

只有 3 个被删除。

现在这通常不会成为问题,我只需使用迭代器来检查值。除了这个特定的练习,for/while/do 循环是明确禁止的……

所以问题似乎出在具有随机访问迭代器的容器上。而且我不确定要实施什么作为替代方案。帮忙?

【问题讨论】:

    标签: c++ stl erase remove-if


    【解决方案1】:

    erase 有几个重载。

    一个重载,你正在使用的那个,接受一个迭代器并擦除迭代器指向的元素。

    您应该使用的另一个重载采用一个范围(一对迭代器)并擦除该范围内的所有元素:

    c.erase(remove_if(c.begin(), c.end(), rg), c.end());
                                             ^^^^^^^^^
    

    [正如你所说,我不确定为什么你的代码“非常适合列表”; std::list 具有与 erase 相同的两个重载。注意std::list还有一个成员函数remove_if,它提供了一个更好的实现擦除/删除算法,专门为std::list优化(由于std::list被实现为链表,它可以实现擦除/删除没有实际移动任何物体)。]

    【讨论】:

    • 非常感谢!正是我需要的。
    【解决方案2】:

    remove_if 将单个迭代器返回到“new last”。那就是将满足您谓词的所有内容打乱到向量中的新最后一个。 new last 之前的所有内容都不满足您的谓词,而过去的所有内容都满足。由于您只为向量中的一个项目执行erase,因此您只删除了新的最后一个项目——这只是满足您的谓词的一件事。相反,您想从新的 last -> end 删除所有满足您谓词的所有内容

    container.erase(
       remove_if(container.begin(), container.end(), rg), 
       container.end()
     );
    

    【讨论】:

      猜你喜欢
      • 2014-06-01
      • 2018-06-07
      • 2019-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多