c++向量; remove_if 只删除单个值?

发布于 2024-12-09 13:27:36 字数 546 浏览 0 评论 0原文

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

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

青柠芒果 2024-12-16 13:27:36

erase 有多个重载。

您正在使用的一种重载采用单个迭代器并删除迭代器指向的元素。

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

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

[我不确定为什么您的代码“非常适合列表”,正如您所说; 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:

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

[I'm not sure why your code "works perfectly for lists," as you say; std::list has the same two overloads of erase. Note that std::list also has a member function, remove_if, which provides a better implementation of the erase/remove algorithm specifically optimized for std::list (since std::list is implemented as a linked list, it can implement erase/remove without actually moving any objects).]

独享拥抱 2024-12-16 13:27:36

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

container.erase(
   remove_if(container.begin(), container.end(), rg), 
   container.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

container.erase(
   remove_if(container.begin(), container.end(), rg), 
   container.end()
 );
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文