How do I efficiently copy an entire queue to a vector/an array in C++? - c++

How do I efficiently copy an entire queue to a vector/an array in C++?
say I have a std::queue and at some point I want to copy it to a vector/an array and then sort it.
Thanks for everyone's answers.
What I really want to do is to create a window with a fix length and at some point i need to copy all the elements inside this window and sort them. the window is moving and there are new data coming in through another interface so i want to use queue. is there any better implementations?

You wrote:
What I really want to do is to create a window with a fix length and at some point i need to copy all the elements inside this window and sort them. the window is moving and there are new data coming in through another interface so i want to use queue.
I suggest to take a step back, and reconsider whether you really want to use a queue. I suppose you want it because you
want to expose a minimal interface to the other component which adds data to the queue.
efficient addition/removal of elements at the front/back (to implement the 'fixed width window' concept)
an efficient way to access the data visible in the window sorted
Unfortunately, std::queue isn't very suitable for (3). Hence, I'd suggest to look for something which addresses (2) and (3), and then consider writing a wrapper of some sort (maybe a plain function which just adds an element to the queue will do?) to implement (1).
For instance, I'd consider using a plain std::deque. It can add/remove elements from the beginning/end of the queue in constant time. It's also very easy to get a sorted view on the window, e.g. if copying the elements of the queue is cheap you could use std::sort like:
std::vector<Elem> sortedView( queue.begin(), queue.end() );
std::sort( sortedView.begin(), sortedView.end() );
...you could of course also do something more clever by not copying the data but rather creating a vector of iterators into the queue, or by using a different sorting algorithm like partial_sort.

If you just want to keep a sorted queue, take a look at priority_queue.

Honestly, the best option is to use the right STL data structure from the start. If you will want to sort the data, a std::queue is not the right data structure.
Consider using a map (or perhaps a hash map). Typical implementations of maps actually build the map sorted, with lookups being performed in O(ln) time. You can still iterate sequentially through a map too, if you really want to.

The only way to access std::queue elements is using a combination of front, back, push, pop since std::queue has no iterators. (In order to be able to use iterators, you should use the underlying container (e.g. std::deque) directly, instead of std::queue.
Since you want to make a copy (presumably leaving the elements in the queue as they were), you can push elements back into the queue after you pop them.
Also, since you know the size of the queue, you can use vector::reserve to prevent expensive memory reallocations triggered by vector::push_back.
So
std::vector<int> V;
std::queue<int> Q;
V.reserve(Q.size());
for(size_t numPos = 0; numPops < Q.size(); ++numPops) {
V.push_back(Q.front());
Q.pop();
Q.push(V.back());
}
std::sort(V.begin(), V.end());

Related

Why is not possible to have a queue implemented as a vector?

What are the drawbacks of using a std::vector for simulating a queue? I am naively thinking that push_back is used for push and for pop one just stores the position of the first element and increments it. Why does not std::queue allow a std::vector implementation like this in principle (I know the reason is it has no push_front method, but maybe there is something deeper that makes it slow this way)? Thank you for helping.
Why does not std::queue allow a std::vector implementation like this
std::queue is a simple container adapter. It works by delegating pop function to the pop_front function of the underlying container. Vector has no pop front operation, so std::queue cannot adapt it.
but maybe there is something deeper that makes it slow this way
Pushing and popping from the front of the vector is slow because it has to shift all elements which has linear cost. This is why vector doesn't provide pop_front.
stores the position of the first element and increments it.
It's possible to implement a container that does store the position of first element within a buffer, but vector is not an implementation of such container. Storing that position has an overhead that vector doesn't need to pay, and so it doesn't.

Efficieny of stl vector and queue

I want to implement a program using either vector or queue data structure. The function requires frequently pushing and popping some elements (e.g. 8 elements) from the data structure to process these elements, and finally the data structure will be empty. The processing order doesn't matter so both vector and queue are ok. I want to know which one has higher efficiency if I need to frequently push and pop from it. Thank you.
std::queue isn't a container. It is a container adapter. By default, it adapts std::deque.
The function requires frequently pushing and popping some elements ... The processing order doesn't matter
This seems to imply that you can pop from the same end where you push (LIFO). In that case, another container adaptor would be appropriate: std::stack. It also adapts std::deque by default. There is no difference in efficiency of std::vector and the efficiency of std::stack that adapts std::vector. There can be a difference in using std::deque depending on the details of how you use it.

C++ Std queue and vector performance

I've been working with graphs lately, and I am looking into returning a path from a graph. The path needs to be returned as a std vector containing all of the nodes with the starting node first.
I've been looking at two options:
- use the slow vector insert method to add the nodes at the front of the vector
- use a deque to add the nodes to the front (push_front), which is much faster. Then copying the deque to the vector using std::copy
Is there a significant performance boost using one method over the other?
Since you're returning a path, you presumably have an upper bound on its length. Therefore, you can call create a vector, call reserve and later (as #user2079303 writes) call push_back to add vertices to the path.
const auto n = <graph_size>
std::vector<size_t> path;
path.reserve(n)
...
v.push_back(i); // Push whatever you want.
Now the problem is that, at least from the question, it seems like v is in the reversed order. However, you can simply call std::reverse:
std::reverse(std::begin(v), std::end(v));
So, using only a vector:
You're allocating a single data structure instead of two; moreover, using reserve there will be a single memory allocation.
The use of reverse at the end simply replaces the use of copy you would have to do from the deque to the vector.
If you are looking at wrapping a std::vector in a std::queue then the std::queue will push elements to the back of the vector (the fast way).
Even if not however, because a std::vector is contiguous storage, it is possible it will out-perform a std::deque even if you push_font() because it plays well with the CPU cache where shuffling data is fast.
But why not try both and profile the code to see which one performs better?

What is the major difference between a vector and a stack?

Both act like a stack. Both have push and pop operations.
Is the difference in some memory layouts?
std::vector has several accessibility and modification operations compared to std::stack. In case of std::stack, you may have to perform operations only in systematic way, where you can push() above the last element or pop() the last element.
std::vector is more flexible in that sense, where it has several operations, where you can insert() in between or erase() in between.
The major point is that, std::stack needs to be provided the underlying container. By default it's std::deque, but it can be std::vector or std::list too.
On other hand, std::vector is guaranteed to be a contiguous array which can be accessed using operator [].
I'm not aware of all the implementation details, but according to this, stack is a container adaptor. It makes sure the underlying container, which can be a vector, list or deque, works as a stack, i.e. only allows push and pop, and not random access.
So, a vector can work as a stack, but a stack cannot work as a vector, because you cannot insert or get an element at a random position.
stack is a stack. It can only push and pop. A vector can do other things, like insert into the middle. This increases flexibility, but reduces guarantees.
For example, for a stack, if you push A then B onto the back then you are guaranteed that they will be removed in the order B, then A. vector doesn't guarantee that.
Stack is basically a special case of vector. Theoretically speaking vector can grow as you wish. You can remove elements at any index in a vector. However, in case of a stack you can remove elements and insert them only at its top (hence a special case of vector).
In face in many libraries that provide an implementation of a stack, they generally inherit from the vector class/structures. I am not sure, but I think STL (C++) does it.
As cplusplus.com suggests:
Stacks are a type of container adaptor, specifically designed to operate in a LIFO context (last-in first-out), where elements are inserted and extracted only from one end of the container.
The key word here is only, as in elements are only inserted and extracted from one end of the container.
You say both vectors and stacks act like stacks, but this is only partially true. Vectors can act like stacks, but they can also act very much not like stacks, by allowing you to do things such as insert at any index, access any element, iterate over the entire structure, etc.
Stacks take a container (such as, for example, a vector) and only permit stack-like interactions with it. This effectively guarantees that all interactions with the container will obey LIFO: only the most recently added element in the container will be able to be accessed or removed.
If you want a container with stack-like behavior, you should use a stack if it is particularly important to you that it behaves exclusively a stack. You should use a vector if you want stack-like behavior but might also want to do things like iterate over elements or modify elements in arbitrary positions etc.
I think the main difference is that vector is a range based container. It can be easily used thanks to its member functions such as begin and end. Vector can be easily initiated with {} form. We can use new features of modern C++ like range-based loops.
vector<int> vec{ 7, 3, 1, 9, 5 };
for ( auto &i : vec ) {
std::cout << i << std::endl;
}
Whereas it is not possible for std::stack.

delete element from priority queue in c++ stl

Is i have a priority queue with declaration
priority_queue<<Node>,vector<Node>,myComp> openQ
i am inserting node objects into it. but at some time i have to delete the element from it. (not to remove the top element)
Currently to delete it i am popping the element and putting it in array. if the top most element is desired then expect it i push other elements in array.
This is like linear search and delete. I know its not efficient and i am looking for some better ways
priority_queue class is designed for using as queue with priorities. And it designed to remove elements with pop function. If you want to get different behavior you should use different class. For instance, std::map.
If you're ready to manually control a consistence of the queue you may take a look on std::make_heap. It's easy to create a max-heap with it. But in this case you need to manually rebuild a queue each time you want to remove an element.
std::set are orderd and can erase elements by value. the underlying datastructure is a binary search tree, thats why its cheaper to erase elements by value.
a priority queue would have to linearly search through the queue, so its possible but just not very efficient, thats why they didnt include it.