1.11M Members

vector::erase

 
0
 

Hi,
I'm trying to 'reduce' a vector using the erase algorithm within a for loop.
The idea is to scan a table looking for equal successive elements. Once equal elements are found, it erases one of the 2 elements. I'm suspecting a problem in the for loop, due to the iterator. What happens to it's value once an element is deleted ?

void faisceau::reduction(int div)
      {
       
        //if (div!=1)
          {    
          std::vector<photon>::iterator iter, itertracker=((*this).tab_photon).begin();     
           for(iter=itertracker; iter!=((*this).tab_photon).end();iter++)
           if ( ((*iter).tps_arrive) == ((*(iter+1)).tps_arrive)  )
                {
	          ((*iter).ponderation)++;
                  ((*this).tab_photon).erase(iter+1);
                  itertracker=iter;
                }
          }   
      }

I found this on a web:

Because vectors keep an array format, erasing on positions other than the vector end also moves all the elements after the segment erased to their new positions,
This invalidates all iterator and references to elements after position or first.

 
0
 

>>What happens to it's value once an element is deleted ?
The iterator is invalidated and you have to start it all over again. Example here: The program will crash after the erase() is executed unless the break statement is there to stop the loop.

#include <vector>
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;

int main()
{
    vector<int> array;
    int i;
    for(i = 0; i < 10; i++)
        array.push_back(i);
    vector<int>::iterator it = array.begin();
    for(i = 0; it != array.end(); it++, i++)
    {
        if(i == 5)
        {
            array.erase(it);
            break;
        }
        cout << *it << "\n";

    }
    cout << "\n";
    for(it = array.begin(); it != array.end(); it++)
    {
        cout << *it << "\n";
    }
	return 0;
}
 
0
 

Okay, I understood that.
And what if I write :

bool b2=false;
           while(b2==false)
           {
              for(iter=itertracker; iter!=((*this).tab_photon).end();iter++)
              if ( ((*iter).tps_arrive) == ((*(iter+1)).tps_arrive)  )
                   {
	             ((*iter).ponderation)++;
                     ((*this).tab_photon).erase(iter+1);
                     itertracker=iter;
                     break;
                   }
              if((itertracker)==( ((*this).tab_photon).end()  )) b2=true;  
           }

will this work ?

 
0
 

>>will this work ?
Maybe -- try it and find out what it will do.

 
0
 

I admit my question was silly! :confused:
I tried it, but it didn't work.
Actually, it compiles, but then the pc starts WORKING HARD(calculating?), and don't stop until I force it to quit.
Would you please help me find the error?

 
1
 

if you want to iterate through a sequence container erasing elements as you go along, you must use the return value of container::erase . the return value is a vald iterator that designates the first element remaining beyond element(s) erased, or end if no such element exists. for example, the following will erase all even numbers from the vector.

std::vector<int> vec(100) ;
  for( int i=0 ; i<vec.size() ; ++i ) vec[i] = i ;
  std::vector<int>::iterator iter = vec.begin() ; 
  while( iter != vec.end()  )
  {
    if( ( *iter % 2 ) == 0 ) iter = vec.erase( iter ) ;
    else ++iter ;
  }

to remove duplicate elements that are adjacent to each other in a specified range, you can use the algorithm std::unique . for example, this will erase adjacent duplicate elements from the vector.

std::vector<int> vec(100) ;
  for( int i=0 ; i<vec.size() ; ++i ) vec[i] = i/10 ;
  vec.erase( std::unique( vec.begin(), vec.end() ), vec.end() ) ;
 
0
 

Beautiful!
Thanks a LOT.
:*

Question Answered as of 6 Years Ago by Ancient Dragon and vijayan121
You
This question has already been solved: Start a new discussion instead
Post:
Start New Discussion
Tags Related to this Article