Possible Duplicate:
Erasing from a std::vector while doing a for each?
I’m trying to implement vertice coloring according to this algorithm;
/*
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
*/
I don’t understand “add v to currentColor.” line but I supposed, it means assing currentColor to v. Therefore what is the “set”? Anyway the problem is erasing element in vector while iterating it. This is the code.
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;
}
I think it2 = uc.erase(it2); line is already general use but It gives run time error.
In the line:
an element pointed by iterator
it2is removed from the vector, elements are shifted in memory in order to fill that gap which invalidatesit2.it2gets a new value and now points to the first element after the the removed one or the end of the vector (if removed element was the last one). This means that after erasing an element you should not advanceit2. An alternative to proposedremove-erase idiomis a simple trick:You can read more about this here.
Edit:
Regarding your comment, you can use a flag to pass the information whether an element has been erased or not, and you can check it when you get out from the inner loop:
After you’ve erased an element from
ucyou need to break from the inner loop. In the next iteration of the outer loop you’ll be able to access the next element in theucthrough a valid iterator.