c++向量; remove_if 只删除单个值?
我应该实现一个从容器中删除一系列值的函数。例如
eraseRange(v, 1.5, 24);
,将从容器 v 中删除任何大于 1.5 且小于 24 的值。我的函数非常适合列表,我使用:
container.erase(remove_if(container.begin(), container.end(), rg));
Where rg 检查它是否在范围内(该部分的实现不是问题,所以我不打算详细说明)。
但是,当为向量调用擦除范围并使用类似的方法擦除值时,只有第一个值被擦除。因此,如果我有一个包含从 1 到 10 的数字的向量,我调用:
eraseRange(v, 3, 7);
只有 3 个被删除。
现在这通常不会成为问题,我只需使用迭代器来检查值。除了这个特定的练习之外,for/while/do 循环是被明确禁止的......
所以问题似乎出在具有随机访问迭代器的容器上。我不确定要实施什么作为替代方案。帮助?
I'm supposed to implement a function that erases a range of values from containers. So
eraseRange(v, 1.5, 24);
for example would delete any value greater than 1.5 and less than 24 from the container v. And my function works perfectly for lists, where I use:
container.erase(remove_if(container.begin(), container.end(), rg));
Where rg checks if it's within the range (the implementation of that part isn't the issue, so I'm not going to elaborate on it).
However, when calling eraseRange for a vector, and using a similar method to erase the values, only the very first value gets erased. So if I were to have a vector with numbers from 1 to 10, and I called:
eraseRange(v, 3, 7);
Only 3 gets deleted.
Now this normally wouldn't be an issue, I would just use an iterator to check the values. Except for this specific exercise, for/while/do loops are explicitly forbidden...
So the problem seems to be with containers that have random access iterators. And I'm not sure what to implement as an alternative. Help?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
erase
有多个重载。您正在使用的一种重载采用单个迭代器并删除迭代器指向的元素。
您应该使用的另一个重载采用一个范围(一对迭代器)并删除该范围中的所有元素:
[我不确定为什么您的代码“非常适合列表”,正如您所说;
std::list
具有相同的两个erase
重载。请注意,std::list
还有一个成员函数remove_if
,它提供了专门针对std::list< 优化的擦除/删除算法的更好实现。 /code> (由于
std::list
是作为链表实现的,因此它可以实现擦除/删除,而无需实际移动任何对象)。]There are several overloads of
erase
.One overload, the one you are using, takes a single iterator and erases the element pointed to by the iterator.
The other overload, which you should be using, takes a range (a pair of iterators) and erases all of the elements in the range:
[I'm not sure why your code "works perfectly for lists," as you say;
std::list
has the same two overloads oferase
. Note thatstd::list
also has a member function,remove_if
, which provides a better implementation of the erase/remove algorithm specifically optimized forstd::list
(sincestd::list
is implemented as a linked list, it can implement erase/remove without actually moving any objects).]remove_if
返回单个迭代器到“new last” 。这就是将满足您的谓词的所有内容打乱到向量中新的最后一个。 new last 之前的所有内容都不满足您的谓词,而它之后的所有内容都满足您的谓词。由于您仅对向量中的单个项目执行 erase ,你只是删除了新的最后一个——这只是满足你的谓词的一件事。相反,您想删除新的最后一个 -> 中的所有内容。 end 这是满足你的谓词的一切remove_if
returns a single iterator to "new last". That is its shuffled everything satisfying your predicate to past new last in the vector. Everything before new last doesn't satisfy your predicate, while everything past it does. Since you're executing the erase for only a single item from the vector, you're only removing the new last -- that is only one thing that satisfied your predicate. Instead you want to erase everything from new last -> end which is everything that satisfied your predicate