Connecting Tech Pros Worldwide Forums | Help | Site Map

Removing elements from vector

kaferro@hotmail.com
Guest
 
Posts: n/a
#1: Nov 23 '06
I cannot relieve that I am working on Thanksgiving, but I am stuck over
something that should be simple. I have a vector that has twenty-four
elements. I need to remove the four elements whose positions equal
zero. The code below only removes two of the four. Any ideas?

logfile << "\n\n\n. . .removing flat positions";
logfile << "vector size=" << componentPerformance.size() << endl;


int position=0;
for (vector<cPerformance>::iterator itr =
componentPerformance.begin();itr!=componentPerform ance.end(); ++itr)
{
position=itr->returnPosition(); //returnPosition() returns a float
logfile << endl << itr->returnSymbol() << "Position=" <<
itr->returnPosition();
if(position==0)
{
logfile << "\tremoving. . . " << itr->returnSymbol();
componentPerformance.erase(itr);
}
}

logfile.close();


dasjotre
Guest
 
Posts: n/a
#2: Nov 23 '06

re: Removing elements from vector


Use typedefs!

if cPerformance is cheep to copy:

typedef ::std::vector<cPerformance container_t;
container_t tmp;
::std::remove_copy_if(componentPerformance.begin() ,componentPerformance.end(),
::std::back_inserter(tmp),
!::boost::bind(::std::not_equal_to<int>(),
::boost::bind(&cPerformance:: returnPosition, _1), 0));

componentPerformance.swap(tmp);

if it is not cheap to copy don't
keep them in a vector,

say container_t is a list
typedef ::std::list<cPerformance container_t;

your loop would look something like:

for(container_t::iterator it = componentPerformance.begin();
it != componentPerformance.end(); ++it)
{
if((*it). returnPosition() == 0)
it = componentPerformance.erase(it);
}

Mirek Fidler
Guest
 
Posts: n/a
#3: Nov 23 '06

re: Removing elements from vector



kaferro@hotmail.com wrote:
Quote:
I cannot relieve that I am working on Thanksgiving, but I am stuck over
something that should be simple. I have a vector that has twenty-four
elements. I need to remove the four elements whose positions equal
zero. The code below only removes two of the four. Any ideas?
>
logfile << "\n\n\n. . .removing flat positions";
logfile << "vector size=" << componentPerformance.size() << endl;
>
>
int position=0;
for (vector<cPerformance>::iterator itr =
componentPerformance.begin();itr!=componentPerform ance.end(); ++itr)
{
position=itr->returnPosition(); //returnPosition() returns a float
logfile << endl << itr->returnSymbol() << "Position=" <<
itr->returnPosition();
if(position==0)
{
logfile << "\tremoving. . . " << itr->returnSymbol();
componentPerformance.erase(itr);
}
}
>
logfile.close();
Classic error :-)

When you "erase" the element, 'itr' in fact points already to next one
(technically, in fact it is invalidated by standard AFAIK). Therefore
++itr at the end of "for" skips the element next to the removed one.

Mirek

Mirek Fidler
Guest
 
Posts: n/a
#4: Nov 23 '06

re: Removing elements from vector



dasjotre wrote:
Quote:
Use typedefs!
>
if cPerformance is cheep to copy:
>
typedef ::std::vector<cPerformance container_t;
container_t tmp;
::std::remove_copy_if(componentPerformance.begin() ,componentPerformance.end(),
::std::back_inserter(tmp),
!::boost::bind(::std::not_equal_to<int>(),
::boost::bind(&cPerformance:: returnPosition, _1), 0));
>
componentPerformance.swap(tmp);
No wonder nobody outside C++ ghetto considers C++ to be language
suitable to do any real work anymore :)
Quote:
for(container_t::iterator it = componentPerformance.begin();
it != componentPerformance.end(); ++it)
{
if((*it). returnPosition() == 0)
it = componentPerformance.erase(it);
}
I believe this code is wrong - it skips elements past removed one.

dasjotre
Guest
 
Posts: n/a
#5: Nov 23 '06

re: Removing elements from vector



Mirek Fidler wrote:
Quote:
dasjotre wrote:
Quote:
Use typedefs!

if cPerformance is cheep to copy:

typedef ::std::vector<cPerformance container_t;
container_t tmp;
::std::remove_copy_if(componentPerformance.begin() ,componentPerformance.end(),
::std::back_inserter(tmp),
!::boost::bind(::std::not_equal_to<int>(),
::boost::bind(&cPerformance:: returnPosition, _1), 0));

componentPerformance.swap(tmp);
>
No wonder nobody outside C++ ghetto considers C++ to be language
suitable to do any real work anymore :)
A call for a simpler example !

inline bool operator == (cPerformance const & l, cPerformance const &
r)
{
return l.returnPosition() == r.returnPosition();
}

cPerformance nulperf(0);

::std::remove_copy(componentPerformance.begin(),co mponentPerformance.end(),
::std::back_inserter(tmp), nulperf);
componentPerformance.swap(tmp);

Which one would teach you more?
Quote:
Quote:
for(container_t::iterator it = componentPerformance.begin();
it != componentPerformance.end(); ++it)
{
if((*it). returnPosition() == 0)
{
Quote:
Quote:
it = componentPerformance.erase(it);
continue;
}
Quote:
Quote:
}
>
I believe this code is wrong - it skips elements past removed one.
Not any more ;)

dasjotre
Guest
 
Posts: n/a
#6: Nov 23 '06

re: Removing elements from vector



dasjotre wrote:
Quote:
Mirek Fidler wrote:
>
Quote:
dasjotre wrote:
Quote:
Use typedefs!
>
if cPerformance is cheep to copy:
>
typedef ::std::vector<cPerformance container_t;
container_t tmp;
::std::remove_copy_if(componentPerformance.begin() ,componentPerformance.end(),
::std::back_inserter(tmp),
!::boost::bind(::std::not_equal_to<int>(),
::boost::bind(&cPerformance:: returnPosition, _1), 0));
>
componentPerformance.swap(tmp);
No wonder nobody outside C++ ghetto considers C++ to be language
suitable to do any real work anymore :)
>
A call for a simpler example !
>
inline bool operator == (cPerformance const & l, cPerformance const &
r)
{
return l.returnPosition() == r.returnPosition();
}
>
cPerformance nulperf(0);
>
::std::remove_copy(componentPerformance.begin(),co mponentPerformance.end(),
::std::back_inserter(tmp), nulperf);
componentPerformance.swap(tmp);
>
Which one would teach you more?
>
Quote:
Quote:
for(container_t::iterator it = componentPerformance.begin();
it != componentPerformance.end(); ++it)
{
if((*it). returnPosition() == 0)
{
Quote:
Quote:
it = componentPerformance.erase(it);
continue;
}
Quote:
Quote:
}
I believe this code is wrong - it skips elements past removed one.
>
Not any more ;)
My humblest appologies.

container_t::iterator it = componentPerformance.begin();
while(it != componentPerformance.end())
{
if((*it).returnPosition() == 0)
it = componentPerformance.erase(it);
else
++it;
}

Good example to argue against hand coded loops

Mirek Fidler
Guest
 
Posts: n/a
#7: Nov 23 '06

re: Removing elements from vector


Quote:
container_t::iterator it = componentPerformance.begin();
while(it != componentPerformance.end())
{
if((*it).returnPosition() == 0)
it = componentPerformance.erase(it);
else
++it;
}
>
Good example to argue against hand coded loops
Good example to teach you check twice before hitting Post button ;)

Do not worry, happens to me all the time.

Mirek

dasjotre
Guest
 
Posts: n/a
#8: Nov 23 '06

re: Removing elements from vector



Mirek Fidler wrote:
Quote:
Quote:
container_t::iterator it = componentPerformance.begin();
while(it != componentPerformance.end())
{
if((*it).returnPosition() == 0)
it = componentPerformance.erase(it);
else
++it;
}

Good example to argue against hand coded loops
>
Good example to teach you check twice before hitting Post button ;)
>
I know, I'm a trigger happy poster :o)

loic-dev@gmx.net
Guest
 
Posts: n/a
#9: Nov 23 '06

re: Removing elements from vector


kaferro@hotmail.com schrieb:
Quote:
I cannot relieve that I am working on Thanksgiving, but I am stuck over
something that should be simple. I have a vector that has twenty-four
elements. I need to remove the four elements whose positions equal
zero. The code below only removes two of the four. Any ideas?
The componentPerformance.erase() update the iterator to the next
element. Hence, if you still want to use your for(...) loop, you have
to change the if statement as follows:

if(position==0)
{
logfile << "\tremoving. . . " << itr->returnSymbol();
componentPerformance.erase(itr);
--itr; // because itr points to the next element.
}

HTH,
Loic.

Salt_Peter
Guest
 
Posts: n/a
#10: Nov 23 '06

re: Removing elements from vector



kaferro@hotmail.com wrote:
Quote:
I cannot relieve that I am working on Thanksgiving, but I am stuck over
something that should be simple. I have a vector that has twenty-four
elements. I need to remove the four elements whose positions equal
zero. The code below only removes two of the four. Any ideas?
>
logfile << "\n\n\n. . .removing flat positions";
logfile << "vector size=" << componentPerformance.size() << endl;
>
>
int position=0;
for (vector<cPerformance>::iterator itr =
componentPerformance.begin();itr!=componentPerform ance.end(); ++itr)
{
position=itr->returnPosition(); //returnPosition() returns a float
logfile << endl << itr->returnSymbol() << "Position=" <<
itr->returnPosition();
if(position==0)
{
logfile << "\tremoving. . . " << itr->returnSymbol();
componentPerformance.erase(itr);
}
}
>
logfile.close();
template the functor...

#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>

struct VerifyPos0
{
bool operator()(const cPerformance& r_x)
{
// a float??
return 0 == static_cast<int>(r_x.returnPosition());
}
};

int main()
{
std::vector< cPerformance componentPerformance;
...

componentPerformance.erase(
std::remove_if( componentPerformance.begin(),
componentPerformance.end(),
VerifyPos0()),
componentPerformance.end() );
...
}

Mirek Fidler
Guest
 
Posts: n/a
#11: Nov 23 '06

re: Removing elements from vector


if(position==0)
Quote:
{
logfile << "\tremoving. . . " << itr->returnSymbol();
componentPerformance.erase(itr);
--itr; // because itr points to the next element.
}
AFAIK Undefined behavior if the first element is removed (--itr will
move before the .begin()).

Mirek

Daniel T.
Guest
 
Posts: n/a
#12: Nov 24 '06

re: Removing elements from vector


In article <1164298604.459363.262980@k70g2000cwa.googlegroups .com>,
kaferro@hotmail.com wrote:
Quote:
I cannot relieve that I am working on Thanksgiving, but I am stuck over
something that should be simple. I have a vector that has twenty-four
elements. I need to remove the four elements whose positions equal
zero. The code below only removes two of the four. Any ideas?
>
logfile << "\n\n\n. . .removing flat positions";
logfile << "vector size=" << componentPerformance.size() << endl;
>
>
int position=0;
for (vector<cPerformance>::iterator itr =
componentPerformance.begin();itr!=componentPerform ance.end(); ++itr)
{
position=itr->returnPosition(); //returnPosition() returns a float
logfile << endl << itr->returnSymbol() << "Position=" <<
itr->returnPosition();
if(position==0)
{
logfile << "\tremoving. . . " << itr->returnSymbol();
componentPerformance.erase(itr);
}
}
>
logfile.close();
componentPerformance.erase( remove_if( componentPerformance.begin(),
componentPerformance.end(),
not1( mem_fun_ref( &cPerformance::returnPosition ) ) ),
componentPerformance.end() );


Or if you have/want to write it out:

vector<cPerformance>::iterator begin = componentPerformance.begin();
vector<cPerformance>::iterator end = componentPerformance.end();
vector<cPerformance>::iterator pos = componentPerformance.begin();
while ( begin != end ) {
if ( begin->returnSymbol() == 0.0 )
++begin;
else
*pos++ = *begin++;
}
componentPerformance.erase( pos, end );

--
To send me email, put "sheltie" in the subject.
Closed Thread