在迭代同一矢量时擦除矢量中的元素
Erase element in vector while iterating the same vector
可能的重复项:
从 std::vector 中删除,同时为每个执行 a?
我正在尝试根据此算法实现顶点着色;
/*
Given G=(V,E):
Compute Degree(v) for all v in V.
Set uncolored = V sorted in decreasing order of Degree(v).
set currentColor = 0.
while there are uncolored nodes:
set A=first element of uncolored
remove A from uncolored
set Color(A) = currentColor
set coloredWithCurrent = {A}
for each v in uncolored:
if v is not adjacent to anything in coloredWithCurrent:
set Color(v)=currentColor.
add v to currentColor.
remove v from uncolored.
end if
end for
currentColor = currentColor + 1.
end while
*/
我不明白"将v添加到currentColor"行,但我想,这意味着将currentColor添加到v。那么什么是"集合"?无论如何,问题是在迭代时擦除矢量中的元素。这是代码。
vector<struct Uncolored> uc;
vector<struct Colored> c;
int currentColor = 0;
struct Colored A;
struct Colored B;
vector<struct Uncolored>::iterator it;
vector<struct Uncolored>::iterator it2;
vector<struct Colored>::iterator it3;
for(it=uc.begin();it<uc.end();it++){
A.id = (*it).id;
uc.erase(uc.begin());
A.color = currentColor;
c.push_back(A);
for(it2=uc.begin();it2<uc.end();it2++) {
it3=c.begin();
while(it3 != c.end()) {
if( adjacencyMatris[(*it2).id][(*it3).id] == 0 ) {
B.id = (*it2).id;
it2 = uc.erase(it2);
B.color = currentColor;
c.push_back(B);
}
it3++;
}
}
currentColor = currentColor + 1;
}
我认为it2 = uc.erase(it2);
行已经是通用的,但它给出了运行时错误。
在行中:
it2 = uc.erase(it2);
迭代器it2
指向的元素从向量中删除,元素在内存中移动以填补使it2
无效的空白。 it2
获取一个新值,现在指向删除的元素或向量末尾之后的第一个元素(如果删除的元素是最后一个元素(。这意味着擦除元素后不应前进it2
。建议remove-erase idiom
的替代方案是一个简单的技巧:
for(it2 = uc.begin(); it2 != uc.end();)
{
...
if(...)
{
it2 = uc.erase(it2);
}
else
{
++it2;
}
...
}
您可以在此处阅读有关此内容的更多信息。
编辑:关于你的评论,你可以使用一个标志来传递一个元素是否被删除的信息,当你从内部循环中出来时,你可以检查它:
for(it2=uc.begin(); it2 != uc.end();)
{
bool bErased = false;
for(it3 = c.begin(); it3 != c.end(); ++it3)
{
if(adjacencyMatris[(*it2).id][(*it3).id] == 0 )
{
B.id = (*it2).id;
it2 = uc.erase(it2);
bErased = true;
B.color = currentColor;
c.push_back(B);
break;
}
}
if(!bErased)
++it2;
}
从uc
中删除元素后,需要断开内部循环。在外部循环的下一次迭代中,您将能够通过有效的迭代器访问uc
中的下一个元素。
不要使用iterator
类型,而是将索引存储到vector
中。当你需要一个迭代器时——也许是为了传递到erase
——你可以说begin() + myIndex
来生成一个迭代器。
这也使循环看起来更熟悉,例如
for(ind=0; ind < uc.size(); ind++) {
vector::erase()
可以使指向向量的迭代器无效。
这将使所有迭代器和对位置(或第一个(及其后续元素的引用无效。
您需要将erase
的结果添加到迭代器中(它将指向擦除后的元素(并因此使用它。请注意,在
for(it=uc.begin();it<uc.end();++it){
A.id = (*it).id;
uc.erase(uc.begin());
...
}
迭代器it
在 uc.erase
后无效,因此后续 ++ 和使用可能会导致运行时错误。
类似地,即使将擦除的结果分配给it2
,调用也可以使it
无效,这不会改变。
你最好的选择是在每次erase()
之后从头开始你的算法,或者如果你可以改变它,以便它可以从erase
返回的迭代器继续,这样做以获得一些效率。
您遇到了运行时错误,因为it2 = uc.erase(it2);
在最后一个删除的元素之后返回迭代器,因此for(it2=uc.begin();it2<uc.end();it2++)
中的it2++
超出了最后一个元素。
尝试在以下位置更改您的 if:
if( adjacencyMatris[(*it2).id][(*it3).id] == 0 ) {
B.id = (*it2).id;
uc.erase(it2);
B.color = currentColor;
c.push_back(B);
break;
}
- 擦除while循环中迭代的元素
- 擦除许多矢量元素,同时使用'auto'
- 擦除是否删除 stl 无序列图元素使用的堆内存
- 调用 erase() 函数是否也会在擦除元素之前更改迭代器值?
- 为什么在功能内擦除元素后不列出更新?
- 在任一方向上迭代容器并擦除元素
- 擦除矢量中的所有元素,直到第一个非零元素C++
- 迭代时擦除设置元素///
- 从向量和对向量中擦除元素的差异
- 如何安全地擦除 std::vector 中的元素
- 如何将某个元素从shared_ptr擦除到对象向量?
- 如何擦除矢量元素中没有特定字符的元素
- 矢量擦除范围内的元素
- 给定一个向量,擦除低于 itemsnum 的元素
- 从地图上擦除元素,然后将其放回原处
- 使用 str.erase() 的索引擦除字符串的元素?
- C 矢量元素擦除与新向量创建
- 迭代一组和擦除元素
- 使用常量键从集合中擦除元素
- 从向量中擦除元素是否也会擦除元素中存在的所有成员向量