ways to delete the element in between with vector?

Discussion in 'C++' started by JH Programmer, Nov 7, 2006.

  1. Hi,

    is there any ways that allow us to delete an element in between?

    say

    int_val[1]: 1
    int_val[2]: 2
    int_val[3]: 3

    we want to delete 2 from int_val
    so that it becomes

    int_val[1]: 1
    int_val[2]: 3

    I have heard of using iterator with erase()
    but it seemed a bit complicated for me

    thank you very much.

    jacky
     
    JH Programmer, Nov 7, 2006
    #1
    1. Advertising

  2. JH Programmer

    Daniel T. Guest

    "JH Programmer" <> wrote:

    > is there any ways that allow us to delete an element in between?
    >
    > say
    >
    > int_val[1]: 1
    > int_val[2]: 2
    > int_val[3]: 3
    >
    > we want to delete 2 from int_val
    > so that it becomes
    >
    > int_val[1]: 1
    > int_val[2]: 3
    >
    > I have heard of using iterator with erase()
    > but it seemed a bit complicated for me


    Do you only want to erase that one element, or do you want to erase all elements with that value?

    If the former, then simply "val.erase( val.begin() + pos );" where 'pos' is the index.

    If the latter, then use the "erase-remove" idiom: "val.erase( remove( val.begin(), val.end(), 2 ), val.end() );"

    --
    To send me email, put "sheltie" in the subject.
     
    Daniel T., Nov 7, 2006
    #2
    1. Advertising

  3. Thank you so much!

    ###########################
    Here are for others to search for this thread
    =================================

    If you want to delete a specific element in the vector "array"
    you use this method

    for (int i = 0; i < data.size(); i++){
    if ( data == data_buffer ){
    pos = i;
    }
    }
    data.erase(data.begin() + pos );

    #############################


    "Daniel T. дµÀ£º
    "
    > "JH Programmer" <> wrote:
    >
    > > is there any ways that allow us to delete an element in between?
    > >
    > > say
    > >
    > > int_val[1]: 1
    > > int_val[2]: 2
    > > int_val[3]: 3
    > >
    > > we want to delete 2 from int_val
    > > so that it becomes
    > >
    > > int_val[1]: 1
    > > int_val[2]: 3
    > >
    > > I have heard of using iterator with erase()
    > > but it seemed a bit complicated for me

    >
    > Do you only want to erase that one element, or do you want to erase all elements with that value?
    >
    > If the former, then simply "val.erase( val.begin() + pos );" where 'pos' is the index.
    >
    > If the latter, then use the "erase-remove" idiom: "val.erase( remove( val..begin(), val.end(), 2 ), val.end() );"
    >
    > --
    > To send me email, put "sheltie" in the subject.
     
    JH Programmer, Nov 7, 2006
    #3
  4. JH Programmer

    Daniel T. Guest

    "JH Programmer" <> wrote:

    > Thank you so much!
    >
    > ###########################
    > Here are for others to search for this thread
    > =================================
    >
    > If you want to delete a specific element in the vector "array"
    > you use this method
    >
    > for (int i = 0; i < data.size(); i++){
    > if ( data == data buffer ){
    > pos = i;
    > }
    > }
    > data.erase(data.begin() + pos );


    Are you sure the above is what you want? It will erase the *last*
    element that has the value data_buffer. So for example, given the array
    { 0, 1, 2, 2, 1, 0 } if you want to erase '1' then the above code will
    produce { 0, 1, 2, 2, 0 } instead of { 0, 2, 2, 1, 0 }

    You are using the loop to find something, so why not put it in a
    function called "find". That will make your code more expressive:

    template < typename T >
    unsigned find( const vector<T>& vec, T buffer )
    {
    unsigned result = vec.size();
    for ( unsigned i = 0; i < vec.size(); ++i )
    if ( vec == buffer )
    result = i;
    return result;
    }

    The above will return the last element that has the value 'buffer' or
    vec.size() if no element has the value.

    Of course, going through the whole container is needless, once you find
    the element you want, you can stop looking...

    template < typename T >
    unsigned reverse_find( const vector<T>& vec, T buffer )
    {
    for ( unsigned i = vec.size(); i > 0; --i )
    if ( vec[i - 1] == buffer )
    return i - 1;
    return vec.size();
    }

    Notice that I'm going through the container backwards because I want to
    find the *last* element with the particular value.

    It just so happens that the standard already has a function like this,
    defined in <algorithm>

    vec.erase( find( vec.rbegin(), vec.rend(), buffer ).base() );

    The above line will do the same thing your code segment does.

    --
    To send me email, put "sheltie" in the subject.
     
    Daniel T., Nov 7, 2006
    #4
  5. Thanks again

    Since I am implementing the deletion of username in the login system,
    because login name is unique, so it works fine.

    but one thing I can think of is that
    we can declare another vector array
    vector<int> pos;

    so

    if (data == data_buf){
    pos.push_back(i);
    }

    but to delete the elements in the array
    we should delete it from the back
    [ 0 1 0 2 3 4 1 0 2]
    so if we want to delete [2]
    pos[1] = 3
    pos[2] = 8

    for (int i = pos.size(); i >= 0; i--){
    data.erase(data.begin() + pos);
    }
    so delete from the back in vector "data"
    will give correct output.
    [0 1 0 3 4 1 0]

    "Daniel T. дµÀ£º
    "
    > "JH Programmer" <> wrote:
    >
    > > Thank you so much!
    > >
    > > ###########################
    > > Here are for others to search for this thread
    > > =================================
    > >
    > > If you want to delete a specific element in the vector "array"
    > > you use this method
    > >
    > > for (int i = 0; i < data.size(); i++){
    > > if ( data == data buffer ){
    > > pos = i;
    > > }
    > > }
    > > data.erase(data.begin() + pos );

    >
    > Are you sure the above is what you want? It will erase the *last*
    > element that has the value data_buffer. So for example, given the array
    > { 0, 1, 2, 2, 1, 0 } if you want to erase '1' then the above code will
    > produce { 0, 1, 2, 2, 0 } instead of { 0, 2, 2, 1, 0 }
    >
    > You are using the loop to find something, so why not put it in a
    > function called "find". That will make your code more expressive:
    >
    > template < typename T >
    > unsigned find( const vector<T>& vec, T buffer )
    > {
    > unsigned result = vec.size();
    > for ( unsigned i = 0; i < vec.size(); ++i )
    > if ( vec == buffer )
    > result = i;
    > return result;
    > }
    >
    > The above will return the last element that has the value 'buffer' or
    > vec.size() if no element has the value.
    >
    > Of course, going through the whole container is needless, once you find
    > the element you want, you can stop looking...
    >
    > template < typename T >
    > unsigned reverse_find( const vector<T>& vec, T buffer )
    > {
    > for ( unsigned i = vec.size(); i > 0; --i )
    > if ( vec[i - 1] == buffer )
    > return i - 1;
    > return vec.size();
    > }
    >
    > Notice that I'm going through the container backwards because I want to
    > find the *last* element with the particular value.
    >
    > It just so happens that the standard already has a function like this,
    > defined in <algorithm>
    >
    > vec.erase( find( vec.rbegin(), vec.rend(), buffer ).base() );
    >
    > The above line will do the same thing your code segment does.
    >
    > --
    > To send me email, put "sheltie" in the subject.
     
    JH Programmer, Nov 7, 2006
    #5
  6. "Daniel T." <> wrote in message
    news:...
    : It just so happens that the standard already has a function like this,
    : defined in <algorithm>
    :
    : vec.erase( find( vec.rbegin(), vec.rend(), buffer ).base() );
    : The above line will do the same thing your code segment does.

    No! Caveat: &*revIter != &*(revIter.base()) !!

    The reverse iterators had to bee shifted, because for example:
    rbegin().base() == end()
    but *rbegin() shall return the last element == *(end()-1)

    So a corrected statement would be:
    vec.erase( find( vec.rbegin(), vec.rend(), buffer ).base()-1 );


    Tricky details...

    hth -Ivan
    --
    http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact form
    Brainbench MVP for C++ <> http://www.brainbench.com
     
    Ivan Vecerina, Nov 7, 2006
    #6
  7. JH Programmer

    Daniel T. Guest

    > "JH Programmer" <> wrote:
    >
    > Since I am implementing the deletion of username in the login
    > system, because login name is unique, so it works fine.


    In that case, I question the wisdom of using a vector. A std::set would
    support faster deletion and insure that there is only one of each name
    in existence.

    > but one thing I can think of is that we can declare another vector
    > array
    > vector<int> pos;
    >
    > so
    >
    > if (data == data buf){
    > pos.push back(i);
    > }
    >
    > but to delete the elements in the array
    > we should delete it from the back
    > [ 0 1 0 2 3 4 1 0 2]
    > so if we want to delete [2]
    > pos[1] = 3
    > pos[2] = 8
    >
    > for (int i = pos.size(); i >= 0; i--){
    > data.erase(data.begin() + pos);
    > }
    > so delete from the back in vector "data"
    > will give correct output.
    > [0 1 0 3 4 1 0]


    The erase-remove idiom is more effecient in general for removing all
    values from a container.

    pos.erase( remove( pos.begin(), pos.end(), 2 ), pos.end() );

    Writing the above out would look something like this:

    unsigned shift_amt = 0;
    unsigned i = 0;
    while ( i < pos.size() ) {
    pos[i - shift_amt] = pos;
    if ( pos == value_to_remove ) {
    ++shift_amt;
    ++i;
    }
    pos.resize( pos.size() - shift_amt );

    This way, each cell is shifted only once, no matter how may of that
    value exist in the container.

    --
    To send me email, put "sheltie" in the subject.
     
    Daniel T., Nov 7, 2006
    #7
  8. JH Programmer

    Daniel T. Guest

    In article <7a887$4550bd61$3e028af2$>,
    "Ivan Vecerina" <> wrote:

    > "Daniel T." <> wrote in message
    > news:...
    > : It just so happens that the standard already has a function like this,
    > : defined in <algorithm>
    > :
    > : vec.erase( find( vec.rbegin(), vec.rend(), buffer ).base() );
    > : The above line will do the same thing your code segment does.
    >
    > No! Caveat: &*revIter != &*(revIter.base()) !!
    >
    > The reverse iterators had to bee shifted, because for example:
    > rbegin().base() == end()
    > but *rbegin() shall return the last element == *(end()-1)
    >
    > So a corrected statement would be:
    > vec.erase( find( vec.rbegin(), vec.rend(), buffer ).base()-1 );
    >
    >
    > Tricky details...


    Good catch, I forgot about that (don't use reverse iterators much.)

    --
    To send me email, put "sheltie" in the subject.
     
    Daniel T., Nov 7, 2006
    #8
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. pmatos
    Replies:
    6
    Views:
    24,044
  2. JH Programmer

    ways to delete the element in between with vector?

    JH Programmer, Nov 7, 2006, in forum: C Programming
    Replies:
    4
    Views:
    257
    riedel
    Nov 8, 2006
  3. Replies:
    8
    Views:
    1,989
    Csaba
    Feb 18, 2006
  4. Javier
    Replies:
    2
    Views:
    606
    James Kanze
    Sep 4, 2007
  5. zl2k
    Replies:
    27
    Views:
    1,635
    Francesco S. Carta
    Sep 7, 2010
Loading...

Share This Page