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

Posted

技术标签:

【中文标题】在 std::multiset 中,如果找到一个元素,是不是有一种函数或算法可以只擦除一个样本(单一或重复)【英文标题】:In std::multiset is there a function or algorithm to erase just one sample (unicate or duplicate) if an element is found在 std::multiset 中,如果找到一个元素,是否有一种函数或算法可以只擦除一个样本(单一或重复) 【发布时间】:2012-02-28 09:05:07 【问题描述】:

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

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

这没关系,但我认为可能会更好。有什么想法吗?

【问题讨论】:

这是一个非常合理的方法。 这种方法是否确保给定的键(“5”)是重复的? 对于multimap: 有没有保证find 会返回哪些元素? (插入顺序?即使在这样的擦除之后?依赖于实现?) 老实说,在使用 multiset 时这是一个不明显的陷阱,它不是最常用的类。 7 年后仍然想知道std::multiset&lt;T&gt;::erase_one_of 在哪里! 【参考方案1】:
auto itr = my_multiset.find(value);
if(itr!=my_multiset.end())
    my_multiset.erase(itr);

我想有一种更清洁的方式来完成同样的任务。但这可以完成工作。

【讨论】:

这与问题中的内容没有什么不同。 我同意!没有任何意义。其他 12 人在答案中看到了一些有用的东西,所以我知道我不会发疯。 永远不要忽视你和其他人一起发疯的可能性:)【参考方案2】:

试试这个:

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

只要能保证集合中存在value即可。这行得通。

【讨论】:

这个sn-p比较干净很好,但是感觉不那么暴露意图。【参考方案3】:
 if(my_multiset.find(key)!=my_multiset.end())
   my_multiset.erase(my_multiset.equal_range(key).first);

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

【讨论】:

与我在问题中提出的解决方案相比,您的代码执行了两次搜索(find + equal_range)而不是一个效率低下的搜索 因为这是相同的复杂性,我非常喜欢这个答案。谢谢【参考方案4】:

我会尝试以下方法。

先调用equal_range(),查找与key相等的元素范围。

如果返回的范围不为空,则 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 );

【讨论】:

我认为问题是要消除一个重复项,而不是所有重复项。 知道这是否比我的解决方案更快,如果是,为什么?【参考方案5】:

这对我有用:

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

如果 val 存在于多重集中。

【讨论】:

【参考方案6】:

我们可以这样做:

multiset<int>::iterator it, it1;
it = myset.find(value);
it1 = it;
it1++;
myset.erase (it, it1);

【讨论】:

矫枉过正。 “指向要从 unordered_multiset 中删除的单个元素的迭代器。”【参考方案7】:
 auto itr=ms.find(value);  
  while(*itr==value)
  ms.erase(value);
  itr=ms.find(value);  
  

试试这个它将删除多重集中所有可用的重复项。

【讨论】:

【参考方案8】:

其实正确答案是:

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

【讨论】:

如果多重集中不存在 value,则会导致 undefined behavior

以上是关于在 std::multiset 中,如果找到一个元素,是不是有一种函数或算法可以只擦除一个样本(单一或重复)的主要内容,如果未能解决你的问题,请参考以下文章

如何在不重载 `operator()`、`std::less`、`std::greater` 的情况下为`std::multiset` 提供自定义比较器?

std::unordered_multiset 的用例

std::multimap::find 将返回哪个元素,类似地 std::multiset::find?

为啥使用 std::multiset 作为优先级队列比使用 std::priority_queue 更快?

C++ std::multiset 删除 查找 重复元素中的特定元素

C++ std::multiset返回值 has no member named ‘first’