gpt4 book ai didi

c++ - std::remove_if 和 erase 不从 std::vector 中移除元素

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:20:49 25 4
gpt4 key购买 nike

我正在练习 leetcode easy 问题。我想使用 lambda 从 vector 中删除_if(这是第一次,太棒了)。我得到一个指向 new_end 的负指针。

#include <vector>
#include <iostream>
#include <algorithm>
#include <functional> // std::greater

using namespace std;
int main()
{
vector<int> a = { 2, 7, 11, 15 };
int target = 9;

auto new_end = std::remove_if(a.begin(), a.end(), [&a, target](const int x)
{
return std::count(a.begin(), a.end(), x) > target;
});
a.erase(new_end, a.end());
return 0;
}

没有错误但是new_end是一个负指针值。

enter image description here

最佳答案

std::remove_if(begin, end, pred) 返回一个 iterator 指向要删除的第一个元素或 end 如果有没有匹配 pred 的元素。后者适用于您的情况:

auto new_end = std::remove_if(a.begin(), a.end(),
[&a, target](const int x) { return std::count(a.begin(), a.end(), x) > target; }
);

new_end 等于 a.end()。该值被调试器打印为垃圾。但是it happens to just works在你的情况下是偶然的。

正如多位评论员所指出的,一旦您的谓词返回了一次 true,范围 [a.begin(), a.end) 被修改,最后一个元素有一个未指定的值1

这使得 std::count(a.begin(), a.end(), x) 返回未指定的值。


建议的解决方法是在 remove_if 开始移动之前制作一份 a 的拷贝。这是通过按值捕获它来完成的:

auto new_end = std::remove_if(a.begin(), a.end(),
[b=a, target](const int x) { return std::count(b.begin(), b.end(), x) > target; }
);

将拷贝初始化为新名称 b 只是强调它是一个拷贝。


1) 来自 std::remove_if :

Iterators pointing to an element between the new logical end and the physical end of the range are still dereferenceable, but the elements themselves have unspecified values (as per MoveAssignable post-condition).

关于c++ - std::remove_if 和 erase 不从 std::vector 中移除元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50701631/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com