在std :: multiset中,如果找到一个元素,则有一个函数或算法可以擦除一个样本(单一或重复)


83

也许这是重复的,但是我没有找到任何搜索内容:erase(value)std::multiset所有具有找到的值的元素调用时,将被删除。我能想到的唯一解决方案是:

std::multiset<int>::iterator hit(mySet.find(5));
if (hit!= mySet.end()) mySet.erase(hit);

可以,但是我认为可能会更好。有任何想法吗 ?


22
这是一种完全合理的方法。
templatetypedef

这种方法是否确保给定的键(“ 5”)重复?
阿伦(Arun)2012年

@ArunSaha:否。但是,如果不是重复的内容,我想将其删除。从我得到的答案中,我感到没有更好的解决方案。也许这个问题最初是愚蠢的:-P
马丁(Martin)

1
对于multimap:是否可以保证find返回哪些元素?(插入顺序?即使在这样的删除之后?是否依赖于实现?)
P Marecki

2
老实说,使用多重集是一个显而易见的陷阱,它不是最常用的类之一。
Predelnik '17

Answers:


32
auto itr = my_multiset.find(value);
if(itr!=my_multiset.end()){
    my_multiset.erase(itr);
}

我可以想象有一种更干净的方法可以达到目的。但这可以完成工作。


7
这与问题无异。
Troubadour

1
我同意!没有任何意义 其他12个人看到了一些有用的答案,所以我知道我不会疯了。
user2251346

6
永远不要忽略您和其他所有人一样疯狂的可能性:)
Apollys支持Monica19

15

试试这个:

multiset<int> s;
s.erase(s.lower_bound(value));

只要可以确保value在设置中存在出口。那个有效。


2
 if(my_multiset.find(key)!=my_multiset.end())
   my_multiset.erase(my_multiset.equal_range(key).first);

这是我想到的在C ++中删除多集中的单个实例的最佳方法


1
与我在问题中提出的解决方案相比,您的代码进行了两次搜索(find + equal_range),而不是效率低下的搜索
Martin

因为这是同样的复杂性,所以我非常喜欢这个答案。谢谢
Crystal

1

我会尝试以下。

首先调用equal_range()以查找等于该键的元素范围。

如果返回的范围是非空的,则erase()一个元素范围(即,erase()它需要两个迭代器),其中:

  • 第一个参数是返回范围内第二个元素的迭代器(即.first返回的过去一个),并且

  • 第二个参数是返回的范围对迭代器的范围.second


阅读templatetypedef的(谢谢!)评论后进行编辑:

如果应该删除一个(而不是全部)重复项:如果所返回的equal_range()对中至少有两个元素,则erase()通过将返回对中的.first传递给的单个迭代器版本来实现第一个元素erase()

伪代码:

pair<iterator, iterator> pit = mymultiset.equal_range( key );

if( distance( pit.first, pit.second ) >= 2 ) {
    mymultiset.erase( pit.first );
}

2
我认为问题是要消除一个重复项,而不是消除所有重复项。
templatetypedef

是否知道这是否比我的解决方案快?如果是,为什么?
马丁

1

这为我工作:

multi_set.erase(multi_set.find(val));

如果val存在于多集中。



-3

实际上,正确的答案是:

my_multiset.erase(my_multiset.find(value));

1
如果在多集中不存在,则会导致未定义的行为
kien_coi_1997
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.