我目前正在使用 int of 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;
}
}
}
}
}
}
}
}
每次运行我的程序时,在删除我们复制的集合时会出现段错误:我的错误在哪里?
好的,谢谢大家,我只是简单地创建了参数const并添加了一个返回值,这样我就可以动态地将每个构造的集合添加到一个新的向量中,并返回这个向量: - )
答案 0 :(得分:0)
问题不在于修改任何集合,它正在修改向量。
从矢量中删除某些内容后会移动元素。首先,这意味着在擦除位置(for-range循环内部使用迭代器)后向量中的迭代器不再有效。其次,如果移位复制和覆盖设置(而不是移动它们),那么所有迭代器都将不再有效。
结果是代码中存在大量未定义的行为。
此外,即使方法有效,最内层循环也不是擦除集合的好方法。这非常非常低效。
至少,您需要重新考虑清除元素的方式。但我认为提出一个通常更好的算法将是更好的方法。
答案 1 :(得分:0)
您正在使用无效迭代器的std::vector::erase函数。因此,range based for loop内的代码会尝试通过容器端访问迭代器。
答案 2 :(得分:0)
基于范围的for
使用的结束迭代器是在循环之前确定的。由于您在迭代期间erase()
,结尾实际上会发生变化。从erase()
的结果中获取迭代器是不够的,因为结束也发生了变化。我认为你可以逃避不使用基于范围的for
循环来删除你的范围。
答案 3 :(得分:0)
尝试创建一个新的向量而不是修改原始向量:
std::vector<std::set<int>> mergeStates(const std::vector<std::set<int>> & vectorE ) {
std::vector<std::set<int>> new_vector;
...
return new_vector;
}