在 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<T>::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::multimap::find 将返回哪个元素,类似地 std::multiset::find?
为啥使用 std::multiset 作为优先级队列比使用 std::priority_queue 更快?