C++如果存在则删除

3

我希望以幂等的方式从容器中删除元素(即,如果元素存在,则删除它,否则不执行任何操作,我可以多次执行此操作,结果相同)

据我所知,使用map :: erase是幂等的,即使键不存在也是安全的。我认为set也是一样的。

那么对于vector(和类似的线性容器)呢? 我知道这个方法很有效:

auto it = std::find(vec.begin(), vec.end(), val);

if (it != vec.end())
  vec.erase(it);

但我在想,有没有一种方法可以不必手动检查 it == vec.end() ?

根据CPP文档,vec.erase(vec.end()) 的行为是未定义的,这意味着我们不能执行 vec.erase(std::find(..))。 是否有任何方法可以为我执行此检查,以便我可以使用一行代码进行remove_if_exist


3
为什么不使用 remove_if 而采用 find/erase 的方式呢?这是因为您只想删除一个特定的元素吗?如果是的话,您可以将其放在 "if" 条件语句中。 - tadman
2
如果存在多个等效值,您想要做什么?是全部删除还是只删除一个?您是否了解“擦除-移除惯用语”(https://en.wikipedia.org/wiki/Erase%E2%80%93remove_idiom)? - Bob__
1
可能是从向量中删除元素的重复问题。 - user2486888
值得一提的是,从C++17开始,您可以将其编写为if (auto it = std::find(...); it != vec.end()) vec.erase(it); - NathanOliver
在早期版本中,您应该能够执行以下操作:if ((auto it = std::find(...)) != vec.end()) vec.erase(it);。在C++11之前,您只需将auto替换为vector<type>::iterator即可。 - Remy Lebeau
显示剩余2条评论
3个回答

3
这里的问题不是幂等性,而是数据访问模型。
关联容器(set、map 等)与序列不同,因为它们具有“键”,所以可以一次完成查找和删除操作。
序列没有键,所以你的比较是不公平的。请注意,关联容器上的等效操作(即按映射值查找——忽略 set,因为奇怪的是它的键 就是 它的值!)与序列容器一样冗长。
话虽如此,erase-remove 惯用法确实令人烦恼(这是为了尽可能在许多算法中将“范围”与其父容器分开;但还是有点麻烦)。没有理由不能存在remove_and_erase,但你需要通过组合removeerase来创建一个实用函数。

请参阅 https://en.cppreference.com/w/cpp/experimental/vector/erase_if。 - peppe

3
那么向量(以及类似的线性容器)怎么办呢?我知道这个代码可以正常工作:
你所知并不正确。你展示的代码也不是幂等的,因为后续调用可能会多次修改同一个向量。真正的幂等调用应该是:
vec.erase( std::remove( vec.begin(), vec.end(), val ), vec.end() );

并且它是一行代码,正如您所希望的那样。


1
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main()
{
   vector<int> vec {1, 2, 3, 4, 5, 6, 7, 8, 9};

   vector<int>::iterator it;

   ((it = find(vec.begin(), vec.end(), 1)) == vec.end()) ? it : vec.erase(it);

   for(int i : vec) 
     cout << i << endl;

   return 0;
}

如果(auto it = find(vec.begin(), vec.end(), 1); it != vec.end()) vec.erase(it); - Lightness Races in Orbit
1
在编程中,使用条件运算符作为“if”语句绝对是一种反模式;请避免使用! - Lightness Races in Orbit
@LightnessRacesinOrbit 这是我会做的方式,但不幸的是这需要 C++17,而这被标记为 C++11。 - NathanOliver
@NathanOliver 轻松英语词典说:“:D”表示“我只是在调皮”。 - Lightness Races in Orbit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接