迭代并删除 std::set 中的元素
我有一个 std::set ,我需要删除类似的相邻元素:
DnaSet::const_iterator next = dna_list.begin();
DnaSet::const_iterator actual = next;
++next;
while(next != dna_list.end()) // cycle over pairs, dna_list is the set
{
if (similar(*actual, *next))
{
Dna dna_temp(*actual); // copy constructor
dna_list.erase(actual); // erase the old one
do
{
dna_temp.mutate(); // change dna_temp
} while(!dna_list.insert(dna_temp).second); // insert dna_temp
}
++actual;
++next;
}
有时程序无法从主循环退出。我认为当我删除 dna_list
中的最后一个元素时,就会出现问题。完成这项任务的正确方法是什么?
I have a std::set
and I need to erase similar adjacent elements:
DnaSet::const_iterator next = dna_list.begin();
DnaSet::const_iterator actual = next;
++next;
while(next != dna_list.end()) // cycle over pairs, dna_list is the set
{
if (similar(*actual, *next))
{
Dna dna_temp(*actual); // copy constructor
dna_list.erase(actual); // erase the old one
do
{
dna_temp.mutate(); // change dna_temp
} while(!dna_list.insert(dna_temp).second); // insert dna_temp
}
++actual;
++next;
}
Sometimes the program can't exit from the main loop. I think the problem happens when I erase the last element in the dna_list
. What's the correct way to do this task?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
使用
actual = next
而不是++actual
。一旦删除
actual
,它就是一个无效的迭代器,因此++actual
会表现得很奇怪。next
应保持不变,因此将actual
分配给next
应该可以。Use
actual = next
rather than++actual
.Once you erase
actual
, it is an invalid iterator, so++actual
will behave strangely.next
should remain intact, so assigningactual
tonext
should work.最好的选择是创建一个使用
similar()
谓词的比较函子。然后您需要做的就是使用该比较函子构造集合,然后就完成了。集合本身会将两个相似的元素视为相同,并且只让第一个元素进入。您可以使用集合
s
:插入元素、删除元素、修改元素 - 并且集合本身将确保集合中不存在两个相似的元素。也就是说,您也可以自己编写算法,即使只是为了替代选择。查看
中的std::adjacent_find()
。它将找到两个连续相同元素的第一次出现;坚持这个立场。找到后,找到从该点开始与这些元素不同的第一个元素。您最终会得到两个迭代器,它们表示一系列连续的相似元素。您可以使用集合的erase()
方法来删除它们,因为它有一个需要两个迭代器的重载。起泡沫,冲洗,重复整套。
Your best option is to create a comparison functor that uses the
similar()
predicate. Then all you need to do is construct the set with that comparison functor and you're done. The set itself will see two similar elements as identical and will only let the first one in.You can work with set
s
: insert elements, remove elements, modify elements -- and the set itself will make sure no two similar elements exist in the set.That said, you can also write an algorithm yourself, if only for an alternative choice. Take a look at
std::adjacent_find()
from<algorithm>
. It will find the first occurrence of two consecutive identical elements; hold on to that position. With that found, find the first element from that point that is different from these elements. You end up with two iterators that denote a range of consecutive, similar elements. You can use the set'serase()
method to remove them, as it has an overload that takes two iterators.Lather, rinse, repeat for the entire set.