erasing from a list within a loop?

G

Gernot Frisch

in a vector I do this:

for (int i=0; i<v.size(); ++i)
{
if (...) {v.erase(v.begin() + i); --i; continue;}
}


.... how to do this with a list?

for (it = l.begin(); it!=l.end(); ++it)
{
if(...) {MYLIST::iterator it2 = it; --it2; l.erase(it); continue;}
}

what if "it == l.begin()" ?? How else to do this?




--
-Gernot
int main(int argc, char** argv) {printf
("%silto%c%cf%cgl%ssic%ccom%c", "ma", 58, 'g', 64, "ba", 46, 10);}

________________________________________
Looking for a good game? Do it yourself!
GLBasic - you can do
www.GLBasic.com
 
K

Karl Heinz Buchegger

Gernot said:
in a vector I do this:

for (int i=0; i<v.size(); ++i)
{
if (...) {v.erase(v.begin() + i); --i; continue;}
}

... how to do this with a list?

for (it = l.begin(); it!=l.end(); ++it)
{
if(...) {MYLIST::iterator it2 = it; --it2; l.erase(it); continue;}
}

what if "it == l.begin()" ?? How else to do this?

for( it = l.begin(); it != l.end; ) {
if(...)
it = l.erase(it);
else
++it;
}
 
J

John Harrison

Karl Heinz Buchegger said:
for( it = l.begin(); it != l.end; ) {
if(...)
it = l.erase(it);
else
++it;
}

With the added bonus that you can use exactly the same code for a
std::vector.

Another alternative is

for( it = l.begin(); it != l.end; ) {
if(...)
l.erase(it++);
else
++it;
}

and this will work for set and maps as well (though not for vectors).

john
 
T

tom_usenet

With the added bonus that you can use exactly the same code for a
std::vector.

That's a very inefficient algorithm though - fine for std::list, but
for std::vector you should use std::remove_if so that it's O(n).

Tom
 
G

Gernot Frisch

for( it = l.begin(); it != l.end; ) {
That's a very inefficient algorithm though - fine for std::list, but
for std::vector you should use std::remove_if so that it's O(n).

Tom

<headscratch, pageflip...>
er... yes. I see... But then I'd have to provide a function for
testing if something would have to be removed. Not easily possible in
my problem, but great idea to remember for further problems. I have a
std::list btw. (I chose it for exaclty this reasons: having to
remove/insert objects at random position).

-Gernot
 
D

Daniel T.

Gernot Frisch said:
<headscratch, pageflip...>
er... yes. I see... But then I'd have to provide a function for
testing if something would have to be removed. Not easily possible in
my problem, but great idea to remember for further problems. I have a
std::list btw. (I chose it for exaclty this reasons: having to
remove/insert objects at random position).

Please show us the code inside the if check, my guess is that it would
be quite easy to provide a function/functor for the testing.
 
G

Gernot Frisch

Daniel T. said:
Please show us the code inside the if check, my guess is that it would
be quite easy to provide a function/functor for the testing.

Yes, sure, it's just that I'm too lazy or don't want to implement new
functions for style reasons. Sounds silly, but that's me...
-Gernot
 
T

tom_usenet

Yes, sure, it's just that I'm too lazy or don't want to implement new
functions for style reasons. Sounds silly, but that's me...

In many cases you can do without a separate function. Have a look at
boost's Lambda library.

Tom
 
G

Gernot Frisch

tom_usenet said:
In many cases you can do without a separate function. Have a look at
boost's Lambda library.

Tom

Huh!? for_each(a.begin(), a.end(), cout << _1;}
How can you provide code as an argument? How does it work?

The boost libraries are the most sophisticated libraries I've ever
seen. I use the boost::spirit library - really a masterpiece of C++
coding. Even though, you'll need to find a good C++ compiler that
really can handle it.

-Gernot
 
D

Daniel T.

Gernot Frisch said:
Yes, sure, it's just that I'm too lazy or don't want to implement new
functions for style reasons. Sounds silly, but that's me...

So, first you say it would not be easy to "provide a function for
testing if something would have to be removed", now you admit that it
would probably be easy but you don't want to do it "for style reasons".

It may be possible to create the test *without* implementing a new
function. Are you willing to show us the code inside the if check to see
if that is possible?
 
G

Gernot Frisch

So, first you say it would not be easy to "provide a function for
testing if something would have to be removed", now you admit that it
would probably be easy but you don't want to do it "for style
reasons".

Not easy _for me_ - anakasm...
It may be possible to create the test *without* implementing a new
function. Are you willing to show us the code inside the if check to see
if that is possible?

Yes, sure:
I have a list<POLYLINE> that defines some regions. The regions [0;
m_PositiveRegions[ are positive, the others ( [m_PositiveRegions;
m_Regions.size[ ) are hole in the previos regions, gettit?
Now I get a safe point inside a hole (for each hole) and see if it's
inside one of the positive areas. If it is, I take the smales one and
assign it as "parant" to the hole.

Here's my piece of crap:



retry:
region_it = m_Regions.begin();
std::advance(region_it, m_PositiveRegions);

for (i=m_PositiveRegions; i<(long)m_Regions.size(); ++region_it, ++i)
{
parent=-1; // Ain't got no parent
minarea = 1e300; // That's a lot
myarea=fabs(PolyArea(*region_it)); // Get Area of the hole

// loop all the positive regions
std::list<POLYLINE>::iterator region2_it; j=0;
for (region2_it=m_Regions.begin(); j<m_PositiveRegions;
region2_it++)
{
area=PolyArea(*region2_it); // Area of positive poly
if(area < minarea && area>myarea+m_Eps) // Has area and is
// smaller than the last
one
{
// Check if region in region
NODE node = GetSafePointInRegion(i); // Get a point that's surely
in
// the region with index 'i'
// Is it in the positive area also?
if (IsPointInRegion(node.x, node.y, j))
{
minarea = area;
parent = j;
}
}
j++;
}
// I don't have a parent - shoot me, noone will shed a tear
if (parent==-1)
{
TRACE("Remove: %d\n", i);
m_Regions.erase(region_it);


goto retry; // Ahrgh! Why can't I continue somehow?


}
else
{
TRACE("%d is hole in %d\n", i, parent);
region_it->m_IsHoleIn=parent;
}
}
 
T

tom_usenet

Huh!? for_each(a.begin(), a.end(), cout << _1;}
How can you provide code as an argument? How does it work?

Hmm, it uses clever template metaprogramming techniques; in
particular, I imagine (I've never looked) it uses expression templates
to build up an object that represents the expression ("cout << _1" in
this case), with much of the information encoded in the type, and then
turns this object into an executable functor. Read up on expression
templates, or there may be some papers online on boost.lambda. Ahh,
here we go:
http://www.oonumerics.org/tmpw01/jarvi.pdf
(see section 4 for a little bit about the implementation)
The boost libraries are the most sophisticated libraries I've ever
seen. I use the boost::spirit library - really a masterpiece of C++
coding. Even though, you'll need to find a good C++ compiler that
really can handle it.

Fortunately most latest version compilers are now good enough to
handle most or even all of Boost; it's been a while coming
(particularly with Microsoft).

Tom
 
G

Gernot Frisch

The boost libraries are the most sophisticated libraries I've ever
Fortunately most latest version compilers are now good enough to
handle most or even all of Boost; it's been a while coming
(particularly with Microsoft).

Sure, but I can't turn on debugging, says: internal compiler error -
stack overfolw or out of memory or something... So I have to debug a
release version... Anyway, the package's great! Never seen writing a
parser that easily.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top