Is there a function to add to the bottom of a c++ stack? - c++

I could always use an array and write an algorithm for pushing items to the top but a stack would probably be more efficient and simpler to use later. I've searched for this function and couldn't find one.

Use a std::deque, which provides both std::deque::push_back and std::deque::push_front methods for pushing elements to the "top" and "bottom" of the data structure, respectively, in constant time.

std::stack is a container adapter, not a container itself. That means it simply enforces a stack interface (which by definition only offers push and pop to the top of the stack) over the top of a user specified underlying container that provides push_back(), pop_back() and back() functions. By default std::stack uses std::deque as its underlying container but std::vector and std::list are standard containers that also meet the requirements (and std::vector is probably a better choice in most cases).
If you want to be able to push to the other end of the stack then just directly use a container that supports that efficiently - std::deque is likely your best choice.

std::stack is a FILO data container, full stop. You can add to the back and then you can remove from the back. If you need to do anything else, then you need to use a container that isn't std::stack.

You seem to be using wrong container for what you want to achieve. deque seems to be a better fit.

Related

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.

std::vector emplace_back vs std::deque push_back?

I have a set of items, which i push back at the end of the container and pop back. For this purpose,
I'm not using std::stack because std::stack is already using std::deque inside. So I'm using std::vector<> and instead of push_back, I'm using emplace_back as i have multiple arguments.
I would like to know is it worth switching to std::deque to improve performance?
Whether it will improve performance or not will depend greatly on your usage pattern: how much you push, how often you pop, how expensive is element copying (or moving) during vector reallocation and so on and so forth. There's no way to say anything definitive without looking at the specifics. Try it, profile it and see which one works better.
BTW, you can specify which container type std::stack will use under the hood. And you also have std::list to try.

When the data structure is a template parameter, how can I tell if an operation will invalidate an iterator?

Specifically, I have a class which currently uses a vector and push_back. There is an element inside the vector I want to keep track of. Pushing back on the vector may invalidate the iterator, so I keep its index around. It's cheap to find the iterator again using the index. I can't reserve the vector as I don't know how many items will be inserted.
I've considered making the data structure a template parameter, and perhaps list may be used instead. In that case, finding an iterator from the index is not a trivial operation. Since pushing back on a list doesn't invalidate iterators to existing elements, I could just store this iterator instead.
But how can I code a generic class which handles both cases easily?
If I can find out whether push_back will invalidate the iterator, I could store the iterator and update it after each push_back by storing the distance from the beginning before the operation.
You should probably try to avoid this flexibility. Quote from Item 2 "Beware the illusion of container-independent code" from Effective STL by Scott Meyers:
Face the truth: it's not worth it. The different containers are
different, and they have strengths and weaknesses that vary in significant ways. They're not designed to be interchangeable, and
there's littel you can do to paper that over. If you try, you're
merely tempting fate, and fate doesn't like to be tempted.
If you really, positively, definitely have to maintain valid iterators, use std::list. If you also need to have random access, try Boost.MultiIndex (although you'll lose contiguous memory access).
If you look at the standard container adapators (std::stack, std::queue) you see that they support the intersection of the adaptable containers interfaces, not their union.
I'd create a second class, which responsibility would be to return the iterator you are interested in.
It should also be parametrized with the same template parameter, and then you can specialize it for any type you want (vector/list etc). So inside your specializations you can use any method you want.
So it's some traits-based solution.
If you really want to stick with the vector and have that functionality maybe take a look at
http://en.cppreference.com/w/cpp/container/vector/capacity function. wrap your push_backs in defined function or even better wrap whole std::vector in ur class and before push_backing compare capacity against size() to check if resize will happen.

STL iterable container like priority_queue

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.

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.