Tommy K
Tommy K

Reputation: 1807

putting elements from vector into queue then clearing vector

I'm looking for the simplest way(algorithm?) to push an entire vector onto a queue and then delete the vector. I think there are a few ways to do this but I'm not sure which is best, or if all of them are correct. Option 1 is to use vector.pop_back(), but I'd have to go backwards through the for loop in this case, which isn't a problem since the order the objects go into the queue from the vector do not matter

for(unsigned i = vector.size() - 1; i >= 0; i--){
    queue.push(vector[i]);
    vector.pop_back();
}

Option 2 is to use vector.erase(). Also is it okay to do i < vector.size()? Because when I looked online for iterating through vectors I found a lot of i != vector.size() instead

for(unsigned i = 0; i < vector.size(); i++){
    queue.push(vector[i]);
    vector.erase[i];
}

My issue here is that if I erase vector[i], does vector [i+1] now become vector[i]? Or does vector[i] become a Null value?

My 3rd option would be to just erase it all at the end

for(unsigned i = 0; i < vector.size(); i++){
    queue.push(vector[i]);
}
vector.erase(vector.begin(), vector.end());

Just for clarity, I don't want to get rid of the vector variable itself, just empty it after putting it into the queue, because it will eventually store a bunch of new things to dump into a queue again and again.

Upvotes: 2

Views: 4011

Answers (4)

BillyT2
BillyT2

Reputation: 329

If you were to use a deque instead of queue then you could do an insert and insert all the elements at once.

Something like

template <class T, template <typename, typename> class Container>
class BlockQueue : public Container<T, std::allocator<T>>
{
public:
    BlockQueue() : Container<T, std::allocator<T>>()
    {
    }
    void push( T val )
    {
        this->push_back( val );
    }
    void push( const std::vector<T>& newData )
    {
        this->insert( this->end(), newData.begin(), newData.end() );
    }
};

Upvotes: 0

Ajay
Ajay

Reputation: 18411

Unless the element-type is large, you can't do much (except move which @Angew suggested). If element size is small, there is no benefit of move either - the memory layout of both vector and queue are different. If element-type is large, you may consider using pointers (in a list or vector) of elements.

Upvotes: 0

Oncaphillis
Oncaphillis

Reputation: 1908

A)

for(unsigned i = vector.size() - 1; i >= 0; i--){
    queue.push(vector[i]);
    vector.pop_back();
}

This should be a bit less efficient then C)

B)

for(unsigned i = 0; i < vector.size(); i++){
    queue.push(vector[i]);
    vector.erase[i];
}

"My issue here is that if I erase vector[i], does vector [i+1] now become vector[i]? Or does vector[i] become a Null value?"

Erase[i] doesn't work at all. You could ruse erase(vector.begin()) pulling elements from the vectors head one by one, but its not very efficient and the whole loop should end up with O(N^2/2) since your deleting from the vectors head.

C)

for(unsigned i = 0; i < vector.size(); i++){
        queue.push(vector[i]);
    }
    vector.clear();

Should be the most efficient way to go.

Note

The result of A and B since in A you're pulling elements from the tail while taking them from the head in C

Upvotes: 0

If you don't mind the objects being present in both the queue and the vector for a while, just do the simplest thing: your 3rd option, just with a clear() instead to be explicit what you're doing:

for(size_t i = 0; i < vector.size(); i++){
    queue.push(vector[i]);
}
vector.clear();

Of course, in C++11, you could use a range-based for loop, and even move the items out of the vector to avoid needless copies:

for (auto &elem : vector) {
  queue.push(std::move(elem));
}
vector.clear();

Upvotes: 3

Related Questions