Thread: shrink c++ vector

  1. #1
    Registered User
    Join Date
    Nov 2007
    Posts
    1

    shrink c++ vector

    Hi,

    I would like to reduce a vector with 9 component to have only 7, throwing away the first and the last and keeping te rest, so that:
    new_vector[0]=old_vector[1]
    new_vector[1]=old_vector[2]
    .....
    new_vector[6]=old_vector[7]

    Can you help me to find an elegant way to do so, please?

    Thanks a lot for your help!!

  2. #2
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Copy the elements to where they should be, then use the resize() method. Note that this does NOT decrease the capacity of the vector. If you actually want to release some memory, you need to play the "swap trick."

  3. #3
    Registered User
    Join Date
    Sep 2006
    Posts
    835
    Keep in mind that adding or deleting elements from a vector anywhere except at the end is relatively expensive since elements after the ones you add or delete have to be copied to their new locations. If you need to efficiently add or delete elements at both ends (but not in the middle) consider using a queue instead of a vector (the elements are not guaranteed to be contiguous in memory, but they probably consist of a small number of contiguous chunks, so cache efficiency should be reasonable). If you need to efficiently add/delete elements anywhere, you would need a list, but a list is much less cache-efficient since its elements may be widely scattered in memory, so avoid it unless your container is very large. If in doubt, profile.

    Edit: Oops, I meant to say deque instead of queue, thanks iMalc.
    Last edited by robatino; 11-01-2007 at 12:41 PM.

  4. #4
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    If you just erase the two elements you no longer need the copying will be done for you. Use erase to erase the first element and pop_back to erase the last (maybe pop_back first to avoid an unnecessary copy of that last element).

  5. #5
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Consider switching to a deque if you frequently remove from both ends, as it is faster for the remove-from-front operation.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  6. #6
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    You need to use the swap technique to remove excess capacity:
    http://www.ubookcase.com/book/Addiso...2lev1sec2.html

    Code:
    container<T>( c ).swap( c ); // the shrink-to-fit idiom to shed excess capacity

  7. #7
    Registered User
    Join Date
    Sep 2006
    Posts
    835
    By using the two-iterator constructor for a vector, the first and last element can be erased and the capacity trimmed in one line:
    Code:
    std::vector<T>(v.begin() + 1, v.end() - 1).swap(v);

  8. #8
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Of course, in removing only two elements, chances are slim that the capacity will be effected anyway. Besides, while it's an interesting conversation I don't think that the OP should care about capacity here, the example has only 9 elements.

  9. #9
    The larch
    Join Date
    May 2006
    Posts
    3,573
    I somehow doubt that OP is interested in reducing memory usage here, just removing the first and last element...

    Anyway you'll need to check first if there is anything to erase from the vector.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  10. #10
    Registered User
    Join Date
    Sep 2006
    Posts
    835
    Quote Originally Posted by Daved View Post
    Of course, in removing only two elements, chances are slim that the capacity will be effected anyway. Besides, while it's an interesting conversation I don't think that the OP should care about capacity here, the example has only 9 elements.
    Definitely - although if one wanted to erase a range of elements at the beginning, and another range at the end, the swap method would be more concise, in addition to offering the possibility of a capacity reduction (the alternative is to call erase() twice, once for each range). In the OP's case, though, it doesn't matter.

  11. #11
    Malum in se abachler's Avatar
    Join Date
    Apr 2007
    Posts
    3,195
    Code:
    Start = 1;
    Stop = 7;
     
    for(x=Start;x<Stop+1;x++) new_vector[x-Start] = old_vector[x];

  12. #12
    The larch
    Join Date
    May 2006
    Posts
    3,573
    If you want a new vector, rather than modifying the old one:
    Code:
    if (old_vec.size() > 1) //there has to be at least two items to remove
        new_vec.assign(old_vec.begin()+1, old_vec.end()-1);
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. can some one please tell me the cause of the error ?
    By broli86 in forum C Programming
    Replies: 8
    Last Post: 06-26-2008, 08:36 PM
  2. syntax help?
    By scoobygoo in forum C++ Programming
    Replies: 1
    Last Post: 08-07-2007, 10:38 AM
  3. Vector class
    By Desolation in forum C++ Programming
    Replies: 2
    Last Post: 05-12-2007, 05:44 PM
  4. Need some help/advise for Public/Private classes
    By nirali35 in forum C++ Programming
    Replies: 8
    Last Post: 09-23-2006, 12:34 PM
  5. Certain functions
    By Lurker in forum C++ Programming
    Replies: 3
    Last Post: 12-26-2003, 01:26 AM