I have a program with a queue of strings. The requirements changed and now the output must be in alphabetical order. I am trying to sort the queue but am getting the error "no matching function call to 'begin(std::queue<std::cxx11__basic::string<char>>&)' and 'end(std::queue<std::cxx11__basic::string<char>>&)'
queue<std::string> lines = doWork();
std::sort(std::begin(lines), std::end(lines));
What's the best way to sort it? Would it be better to change from a queue to a vector or some other structure? The thing is the only operations needed is to add to end and remove from end.
Also I'm using Netbeans and it only displays the compile error messages when I hover over the red x so how can I copy and paste the message?
EDIT: I now understand queues can't be sorted. So what then is the best data structure to use? It only needs to be added to from one end, sorted and red linearally (from start to end)?
This is std::queue. It has no begin and end - that would defeat the purpose of the wrapper. Choose std::vector instead or use std::priority_queue.
std::queue has no begin and end, the order is always FIFO by definition.
Choose std::deque instead, it can be sorted and, unlike std::vector, has pop_front and offers better performance for FIFO operations.
Related
I have a list of elements that is almost in the correct order and the elements are just off by a relatively small amount of places compared to their correct position (e.g. no element that is supposed to be in the front of the list is in the end).
< TL;DR >
Practical origin: I have an incoming stream of UDP-Packages that contain signals all marked with a certain timestamp. Evaluating the data has shown, that the packages have not been send (or received) in the right order, so that the timestamp is not constantly increasing but jittering a bit. To export the data I need to sort it in advance.
< /TL;DR >
I want to use std::list.sort() to sort this list.
What is the sorting algorithm used by std::list.sort() and how is it affected by the fact that the list is almost sorted. I have a "feeling", that a divide-and-conquer based algorithm might profit from it.
Is there a more efficient algorithm for my quite specific problem?
If every element is within k positions of its proper place, then insertion sort will take less than kN comparisons and swaps/moves. It's also very easy to implement.
Compare this to the N*log(N) operations required by merge sort or quick sort to see if that will work better for you.
It is not defined which algorithm uses, allthough it should be around N log N on average, such as quicksort.
If you are appending packets to the end of the "queue" as you consume them, so you want the queue always sorted, then you can expect any new packets correct position to nearly always be near the "end".
Therefore, rather than sorting the entire queue, just insert the packet into the correct position. Start at the back of the queue and compare the existing packets timestamp with those already there, insert it after the first packet with a smaller timestamp (likely to always be the end) or the front if there is no such packet in the event things are greatly out of order.
Alternatively, if you want to add all packets in order and then sort it, Bubble Sort should be fairly optimal because the list should still be nearly sorted already.
On mostly-sorted data Insertion Sort and Bubble Sort are among the most common ones that perform the best.
Live demo
Note also that having a list structure puts an extra constraint on indexed access, so algorithms that require indexed access will perform extra poorly. Therefore insertion sort is an even better fit since it needs only sequential access.
In the case of Visual Studio prior to 2015, a bottom up merge sorting using 26 internal lists is used, following the algorithm shown in this wiki article:
https://en.wikipedia.org/wiki/Merge_sort#Bottom-up_implementation_using_lists
Visual Studio 2015 added support for not having a default allocator. The 26 internal lists initializers could have been expanded to 26 instances of initializers with user specified allocators, specifically: _Myt _Binlist[_MAXBINS+1] = { _Myt(get_allocator()), ... , _Myt(get_allocator())};, but instead someone at Microsoft switched to a top down merge sort based on iterators. This is slower, but has the advantage that it doesn't need special recovery if the compare throws an exception. The author of that change pointed out the fact that if performance is a goal, then it's faster to copy the list to an array or vector, sort the array or vector, then create a new list from the array or vector.
There's a prior thread about this.
`std::list<>::sort()` - why the sudden switch to top-down strategy?
In your case something like an insertion sort on a doubly linked list should be faster, if an out order node is found, remove the from the list, scan backwards or forwards to the proper spot and insert the node back into the list. If you want to used std::list, you can use iterators, erase, and emplace to "move" nodes, but that involves freeing and reallocating a node for each move. It would be faster to implement this with your own doubly linked list, in which case you can just manipulate the links, avoiding the freeing and reallocation of memory if using std::list.
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());
I'm new to STL containers (and C++ in general) so thought I would reach out to the community for help. I basically want to have a priority_queue that supports constant iteration. Now, it seems that std::priority_queue doesn't support iteration, so I'm going to have to use something else, but I'm not sure exactly what.
Requirements:
Maintains order on insertion (like a priority queue)
Pop from top of list
Get const access to each element of the list (don't care about the order in the queue for this stage)
One option would be to keep a priority_queue and separately have an unordered_set of references, but I'd rather not have two containers floating around. I could also use a deque and search through for the right insertion position, but I'd rather have the container manage the sorting for me if possible (and constant-time insertion would be nicer than linear-time). Any suggestions?
There are two options that come to mind:
1) Implement your own iterable priority queue, using std::vector and the heap operation algorithms (see Heap Operations here).
2) derive (privately) from priority_queue. This gives you access to the underlying container via data member c. You can then expose iteration, random access, and other methods of interest in your public interface.
Using a std::vector might be enough as others already pointed, but if you want already-ready implementation, maybe use Boost.Heap (which is a library with several priority queue containers): http://www.boost.org/doc/libs/1_53_0/doc/html/heap.html
Boost is a collection of libraries that basically complete the standard library (which is not really big). A lot of C++ developers have boost ready on their dev computer to use it when needed. Just be careful in your choices of libraries.
You can use (ordered) set as a queue. set.begin() will be your top element, and you can pop it via erase(set.begin()).
Have you observed heap (std::make_heap) ? It hasn't order inside of queue, but has priority "pop from top of list" which you need.
The std::queue is implemented with a deque by default. std::deque has the subscript operator, operator[], and is probably implemented with arrays. So why doesn't std::queue have operator[]?
I realize you could have a queue with a list as the underlying container. (std::queue<int, std::list<int>>.) But even if that would make the subscript operator slow, is that really a good reason not to include it? That's the only reason I can think of that it is not included.
Because the definition of queue doesn't support such interface. Queue is a FIFO data structure which means First In First Out. Queue supports enqueue and dequeue operations.
Imagine of queue as pipe : you insert data into one end and from the other end you take it out - one by one. Inserting data is called enqueue and taking them out is called dequeue. The C++ standard library has std::queue which defines both these operations: push() is the name of enqueue operation, and dequeue operation has been splitted into two steps namely front() followed by pop(). The rationale why dequeue has been split into two steps is to give strong exception guarantee1.
Wikipedia explains this briefly,
A queue is a particular kind of collection in which the entities in the collection are kept in order and the principal (or only) operations on the collection are the addition of entities to the rear terminal position and removal of entities from the front terminal position. This makes the queue a First-In-First-Out (FIFO) data structure. In a FIFO data structure, the first element added to the queue will be the first one to be removed. This is equivalent to the requirement that once an element is added, all elements that were added before have to be removed before the new element can be invoked. A queue is an example of a linear data structure.
1. If you want to know how exacly it gives strong exception guarantee, then you can start another topic, because it's very long story, and requires lots of patience to understand it properly. I would suggest you to read Exceptional C++ by Herb Sutter for this.
It's a concept issue. In a queue, you add to the back and take from the front, not from the middle
The reason not to include it because a queue is a data structure with enqueue and dequeue operations, not random access. std::queue exists to adapt an existing container into a queue interface, so it only provides the queue interface.
If you want to use [] then use a deque with push_front and back/pop_back not a queue.
Why a double ended queue has it but not a queue doesn't make sense to me either.
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.