86

I need to insert values into the beginning of a std::vector and I need other values in this vector to be pushed to further positions for example: something added to beginning of a vector and values moved from position 1 to 2, from 2 to 3 etc.

How can I do that?

NAND
  • 663
  • 8
  • 22
Paweł Szymkowicz
  • 881
  • 1
  • 6
  • 3
  • 12
    Keep in mind that pushing stuff to the front of the vector is an O(n) operation, so if you need to do it repeatedly you probably want to use a data structure better optimized for that (such as `std::deque`), or use other tricks (e.g. if you only add and remove stuff at the front, just do that at the end and display it in reverse). – Matteo Italia Jan 14 '18 at 15:57

5 Answers5

114

Use the std::vector::insert function accepting an iterator to the first element as a target position (iterator before which to insert the element):

#include <vector>

int main() {
    std::vector<int> v{ 1, 2, 3, 4, 5 };
    v.insert(v.begin(), 6);
}

Alternatively, append the element and perform the rotation to the right:

#include <vector>
#include <algorithm>

int main() {
    std::vector<int> v{ 1, 2, 3, 4, 5 };
    v.push_back(6);
    std::rotate(v.rbegin(), v.rbegin() + 1, v.rend());
}
Ron
  • 14,674
  • 4
  • 34
  • 47
  • 2
    I wouldn't call the first parameter of `insert` a hint, I'd say it's more like a target position. – Matteo Italia Jan 14 '18 at 15:58
  • It is working, thanks a lot. And i have another question. I made loop that compares 2 vectors and when values doesn't match, code is inserting the wrong value to the beginning of the vector. How do i now delete the wrong value from the old position? – Paweł Szymkowicz Jan 14 '18 at 16:11
  • 3
    @PawełSzymkowicz: Use `std::rotate` to get it to the first position. Cleaner and more efficient than inserting and deleting. – Jerry Coffin Jan 14 '18 at 16:12
  • @JerryCoffin you mean rotate and then resize to remove the last element? That makes me wonder if there is any use of `push_back` & `rotate` to effectively `push_front`... – 463035818_is_not_an_ai Jun 15 '18 at 09:53
  • He was asking about getting the equivalent of push_front, so yes, what I meant was a push_back followed by a rotate. – Jerry Coffin Jun 16 '18 at 00:33
  • 2
    @JerryCoffin Why `push_back`&`rotate` is faster than `insert`? – Hope Jun 19 '21 at 09:04
  • 1
    @Hope: note the comment about doing inserting and deleting. If we only needed to insert a value, then yes insert would be the obvious choice. But at least as I read it, we're deleting one, and inserting another (in a different place, so we can't just overwrite the existing value). It's not 100% certain that push_back/rotate will be faster though--he's kind of vague about some details. OTOH, given that we're apparently primarily adding to the front in one case, it's probably also worth considering using a `deque`. – Jerry Coffin Jun 20 '21 at 03:18
  • @JerryCoffin Alright, but if we are using a vector, the argument is that the rotate is faster because it is not an O(n) operation like insert, right? – Ac Hybl Aug 12 '21 at 03:16
  • Shouldn't the compiler be sophisticated enough to do this optimization automatically? – northerner Dec 31 '21 at 06:01
35

You should consider using std::deque. It works alot like a std::vector but you can add and remove items from both the front and the end.

It does this by dividing the internal storage up into smaller blocks. You still have random-access iterators with good lookup speed.

If your container is small it should be fine to use the std::vector approach but if you are storing large amounts of data the std::deques performance for inserting/deleting at the front will be far superior.

super
  • 12,335
  • 2
  • 19
  • 29
0

What about this?

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

int main()
{ 
    std::vector<int> v1 = { 1, 2, 3 };
    std::vector<int> v2 = { 4, 5, 6 };

    // merge
    std::vector<int> dst;
    std::merge(v1.begin(), v1.end(), v2.begin(), v2.end(), std::back_inserter(dst));
}

Finally dst is: {1, 2, 3, 4, 5, 6}

Note: It is a sample, so you should check if v1 is empty etc.

75ntamas
  • 123
  • 5
-1

You may try this

    vector<int> v={1,2,3,4,5};
    for(int i=0;i<5;i++){
        v.insert(v.begin(),i+1);
    }

Output is {5,4,3,2,1,1,2,3,4,5}

Every element is shifted to the right after insertion

-2

You can insert values to std::vector from back and then use std::reverse:

Example:

#include <vector>
#include <algorhitm>
#include <iostream>

void printVector( std::vector< int > const & _vector )
{
    for( auto value : _vector )
    {
         std::cout << value << " ";
    }

    std::cout << std::endl;
}

int main()
{
    std::vector< int > someVec;
    
    someVec.push_back( 5 );
    someVec.push_back( 4 );
    someVec.push_back( 3 );
    someVec.push_back( 2 );
    someVec.push_back( 1 );

    // (1)
    printVector( someVec );

    std::reverse( someVec.begin(), someVec.end() );
    
    // (2)
    printVector( someVec );

    return 0;
}

Output (1):

5 4 3 2 1 

Output (2):

1 2 3 4 5