我当前正在处理一个功能,可以使用 int 的向量。我希望我的函数 merge()合并所有共享INT的集合,例如,我希望发生这种情况:
[0] - 0, 1, 2
[1] - 1, 3 Then it will [0] - 0, 1, 2, 3
[2] - 0, 3 output this vector -> [1] - 4, 5
[3] - 4, 5 [2] - 6, 7, 8, 9
[4] - 6, 7, 8
[5] - 8, 9
我已经编写了此功能,其中介绍了哪个代码。我几乎已经评论了每一行,因此不难理解我的代码!
// Merges all sets that shares at least one int
//
// PARAMETERS...
// vectorE : vector of sets of int
void mergeStates( std::vector< std::set< int > >& vectorE )
{
// For every set of ints
for( auto ¤tSet : vectorE )
{
// For every ints of the set
for( auto currentInt : currentSet )
{
// The two for( ) loops down there allow me to iterate over
// every int of every set of the vectorE
for( auto setToCheck : vectorE )
{
// If the set is different from the one we're already targeting
if( currentSet != setToCheck )
{
for( auto intToCheck : setToCheck )
{
// if we have found an int that is the same as the one we're targeting
if( intToCheck == currentInt )
{
// Merge
etatsetEtudie.insert( setToCheck.begin(), setToCheck.end() );
// Deleting the set we copied from, because we won't need it anymore
for(auto setToErase = vectorE.begin() ; setToErase != vectorE.end() ; ){
if( *setToErase == setToCheck )
setToErase = vectorE.erase( setToErase );
else
++setToErase;
}
}
}
}
}
}
}
}
每次运行程序时,我都会在删除我们从哪里复制的集合时得到一个segfault:我的错误在哪里?
编辑:我让它工作!
好吧,谢谢,我只是制作了我的参数const并添加了一个返回值,以便我可以动态地添加我需要的每个构造集,然后返回此向量: - )
问题没有修改任何集,它正在修改向量。
从矢量中删除某些东西会在其之后移动元素。首先,这意味着在擦除位置(内部内部使用迭代器使用的迭代器)之后进入向量的迭代器不再有效。其次,如果复制和覆盖集合(而不是移动它们),则所有迭代器都将不再有效。
结果是您的代码中有很多未定义的行为。
另外,即使方法有效,您的最内向循环也不是擦除该集合的好方法。这非常非常低效。
您至少需要重新考虑擦除元素的方式。但是我认为,提出一种更好的算法将是更好的方法。
尝试制作一个新的向量,而不是修改原始矢量:
std::vector<std::set<int>> mergeStates(const std::vector<std::set<int>> & vectorE ) {
std::vector<std::set<int>> new_vector;
...
return new_vector;
}
您正在使用std :: vector :: erase函数,无效 iterators。因此,基于循环的范围内的代码试图访问容器端的迭代器。
基于范围的 for
使用的末端迭代器是在循环之前确定的。由于您在迭代期间erase()
,因此结束实际上会发生变化。从erase()
的结果中获得迭代器是不足的,因为末端也发生了变化。我认为您可以不使用基于范围的 for
循环来删除的范围。