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

问题描述 投票:0回答:11

也许这是重复的,但我没有找到任何搜索内容: 当在

erase(value)
上调用
std::multiset
时,所有具有找到的值的元素都将被删除。我能想到的唯一解决方案是:

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

这还可以,但我想可能会有更好的。有什么想法吗?

c++ stl multiset
11个回答
49
投票
auto itr = my_multiset.find(value);
if(itr!=my_multiset.end()){
    my_multiset.erase(itr);
}

我想有一种更干净的方法可以实现同样的目的。但这就完成了工作。


44
投票

试试这个:

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

只要能保证集合中存在

value
即可。这有效。


4
投票
 if(my_multiset.find(key)!=my_multiset.end())
   my_multiset.erase(my_multiset.equal_range(key).first);

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


3
投票

这对我有用:

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

如果 val 存在于多重集中。


2
投票

我会尝试以下方法。

首先调用

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 );
}

1
投票

自 C++17 起(请参阅此处):

mySet.extract(val);

0
投票

我们可以做这样的事情:

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

0
投票

这里有一个更优雅的解决方案,使用 C++17 中引入的“带有初始化器的 if 语句”:

if(auto it = mySet.find(value); it != mySet.end())
    mySet.erase(value);

这种语法的优点是迭代器

it
的范围缩小到这个
if
语句。


0
投票

一种方法是使用 cpp17 中的

extract
方法。

如果容器中有一个元素的键等于 k,则 从容器中取消包含第一个此类元素的节点,并返回拥有该元素的节点句柄。否则,返回一个空节点句柄。


-1
投票
 auto itr=ms.find(value);  
  while(*itr==value){
  ms.erase(value);
  itr=ms.find(value);  
  }

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


-2
投票

事实上,正确答案是:

my_multiset.erase(my_multiset.find(value));
© www.soinside.com 2019 - 2024. All rights reserved.