The fastest dynamic data structure in C++ [closed] - c++

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I've got a task which mainly consist in adding or removing elements from an array in C++. Since arrays ain't dynamic but operations on them are very fast, I've been looking for a dynamic data structure which is nearly as fast to operate. I've been thinking about std::vector but since it is predefined and quite massive construct I'm afraid about time of the operations which is crucial for me. Could Anybody provide me with some information about Your point of view? I'd be very glad for any help from You!
edited:
I'm really sorry I haven't included all important point in my question; below I'd try to add more info:
I'll be traversing elements of the structure many times and access them in a random manner so operation on elements on every possible positions are possible
I think that there will be (depending on tests provided) many operations on elements in the middle of the data structure as well as near its "brims".
I believe that will help my post to be more clear, specific and, thus, more useful for others.
Thank You for all the answers!

Refer to Mikael Persson's "container choice" diagram:
http://www.cim.mcgill.ca/~mpersson/pics/STLcontainerChoices.png

The different data structures were implemented in the STL to be used for different reasons. Therefore the structures differ when it comes to insertion/deletion speeds at the start, the middle or the end of the structures or even when it comes to the random access of the structure elements.

A nice short comparison of STL containers:
http://john-ahlgren.blogspot.com/2013/10/stl-container-performance.html
If it's possible for you to use an associative array, maps at least guarantee an insertion/look-up time of O(log n) which is a good bit faster for large amounts of data/lots of insertions and deletes than vector's guarantee of O(n) for non-back insertions.
Not sure if they will work here or not, this link also shows some graphs of benchmarks using random insert/removes/searches/fills/sorts, etc. on several different containers:
http://www.baptiste-wicht.com/2012/12/cpp-benchmark-vector-list-deque/
Lastly, a flow chart from SO that could help you decide on a container:
In which scenario do I use a particular STL container?
While not perfect, it still might turn out that a vector is your best bet.

Will a linked list implemented using an array meet your needs?
class AList
{
public:
AList()
{
for (int = 0; i != 256; ++i )
{
nodes[i].prev = (i-1+256)%256;
nodes[i].next = (i+1)%256;
}
}
int const& operator[](int index)
{
// Deal with the case where nodes[index].isSet == false
return nodes[index].data;
}
// Not sure what the requirements are for adding
// and removing items from the list.
//
// add();
// remove();
private:
struct Node
{
Node() : data(0), prev(0), next(0), isSet(false) {}
int data;
unsigned char prev;
unsigned char next;
bool isSet;
};
Node nodes[256];
};

Related

std::reduce with multiple 3d unordered_maps ( summing values for identical keys) [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed yesterday.
Improve this question
I have a 16 thread generating their outputs to 3d unordered_maps with the following signature
std::unordered_map<int, std::unordered_map<int, std::unordered_map<int, int>>> parameter_space;
What I am trying to do is to merge all those 16 3d unordered_maps into 1. As you can imagine this is incredibly slow.
I was Then drawn to std::accumulate followed by std::reduce.
The problem is the syntax is very complex (at least for me).
I was wondering if someone here could point me in the right direction.
I unsuccessfully tried to create the syntax for std::reduce or std::accumulate for multiple 3d unordered_maps
The way to accumulate the maps would be something like this:
using my_map = std::unordered_map<int, std::unordered_map<int, std::unordered_map<int, int>>>;
void accumulate(my_map& accu,const my_map& add) {
for (const auto& mapmap : add) {
const auto& mapmapkey = mapmap.first;
for (const auto& map : mapmap) {
const auto& mapkey = map.first;
for (const auto& element : map) {
const auto& key = element.first;
accu[mapmapkey][mapkey][key] += element.second;
}
}
}
}
This can be called in a loop for all maps to be accumulated.
You might think that deep nesting of loops is what makes this slow, though that deep nesting is merely a consequence of the container you are using. It iterates all elements in add not more not less.
I suggest to try a std::unordered_map< std::tuple<int,int,int>, int> rather than the deeply nested map you are using currently. Not for performance but for clarity and readability of the code. Or even better use a custom structure as key where you can give the ints a proper name.
For performance you need to measure. Standard algorithms are usually not slower than handwritten loops, but there is also no reason to expect them to be faster. They are not magic. Their main advantage is not speed, but expressiveness. When you have problems to express an algorithm in terms of standard algorithms then trying hard to use them has no inherent advantage. You can always write the code without standard algorithms and only later consider to refactor it. If the handwritten loop is too slow then the algorithm can be expected to be slow too.

Pre-allocating memory for linked list [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
In a technical interview, the guy asked me that "he wants to pre-allocate memory for a linked list just like we can do for array", so how would he do that?
I have never felt the need to, neither came across this thought! I mostly code in C++, and I answered something like "just like we use the new command in C++ for memory allocation, example int *p = new int[10] ,where I can allocate 40 bytes of memory, I'd do something same for my Linked List, like Node *p = new Node()[10] , where Node is my Linked List class name, which is like this:
class Node{
public:
int data;
Node *next;
};
".
Then he further followed it up with how would you go about implementing this and would it really save time, considering space is not an issue? I mainly fumbled my way through the answer and he moved on the next question.
But I'd really like to know now if I was correct and a small example of it's working/operation would really help. Thank you.
Interview questions are generally asked not to be answered directly, and it is expected that you narrow down the use-case and requirements.
he wants to pre-allocate memory for a linked list just like we can do for array
If that is actually the question, then the interviewer either intentionally asked it wrong or misleading. And array (std::array or c-style array) will not only allocate the memory for the types they store but also construct them (at least for non-primitives) so it is important to know if it is a general-purpose list or a specialist list for certain types. A std::vector, on the other hand, actually pre-allocates memory.
You generally want to minimize the number of individual memory allocations because those can be expensive.
I'd do something same for my Linked List, like Node *p = new Node()[10]
You don't want to do that because this would already construct the type managed by the list for each node. In the case of primitives, this won't be much of a problem, but would horribly fail for a general-purpose list like std::list.
Then he further followed it up with how would you go about implementing this and would it really save time, considering space is not an issue?
You would allocate a larger chunk of memory (similar to what std::vector does), and when an element is stored in the list, you will use placment new, to construct the node in the already pre-allocated space.
If space is not a problem and a list would pre-allocate space for, e.g. 100 elements, it would save 99 memory allocations per 100 stored objects. You surely need to add some cost for manually keeping track of which parts of the pre-allocated spaces are free and which one is not, but that is likely to be cheaper than allocating memory.
This is just a rough idea about pre-allocating memory for a list. But the question is missing too many pieces of information to answer it in a meaningful full way.
how would you go about implementing this
We sure can create nodes without actually storing data in it. We can use a constructor (of the linked list) to get it done.
class LinkedList {
public:
LinkedList(int n)
{
pRootNode = new Node();
Node* pTraveler = pRootNode;
for(int i = 0; i < n; i++)
{
pTraveler->next = new Node();
pTraveler = pTraveler->next;
}
}
I'd do something same for my Linked List, like Node *p = new Node()[10]
This will give you an array of nodes. You further need to process it so that the previous node contains the pointer to the next.
would it really save time
A linked list like this will improve insertions as we don't need to allocate new nodes (until a new node is needed) when inserting a new entry. But instantiation of the linked list will take a small time (comparatively) as we are allocating nodes in the constructor.
Linked lists are said to have O(1) insertions and deletions with a worst case of O(n) access/ lookup time. So in my opinion, pre-allocating will have little effect because you'll anyway spend an equal amount of time allocating nodes.

Inserting elements into a linked list C++ [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
Given the EleList class how do I go about writing the implementation of the Insert() function?
I've never really used pointers so this simple problem really has me stumped, I would appreciate a link to relevant learning material if possible.
class EleList
{
public:
EleList( char cData )
: m_cData(cData)
, m_Left(0)
, m_Right(0)
{
}
static void Insert( EleList* InsertEle,
EleList* InsertPos);
private:
char m_cData;
EleList* m_Left;
EleList* m_Right;
};
// Insert() function
void EleList::Insert( EleList* InsertEle,
EleList* InsertPos)
{
}
Pointers seem a bit tricky in the beginning. I strongly recommend you to draw in paper the algorithm you want to implement when it involves data structures and pointers, before doing any code. A linked list is a good way to start to learn them.
Into the implementation you can take several approaches, because you have to consider different cases:
Inserting at the beginning of a list or in an empty list: we create the node and swap the left pointer with the head of the list.
Inserting in the middle of a list: we iterate the list with an auxiliary pointer until the desired position, we create the new node and redirect the necessary pointers (the ones of the new node and the ones from the neighbour nodes).
Inserting at the end of the list: we iterate until the last element, create the new node and attach them to each other with the pointers.
You can try to implement one and from there try another. If you are learning, it doesn't have to be perfect, it has to make you understand how pointers and data structures work.
I'm sure you will find this link useful, it's very complete and has an extensive example in code.

How can I dirty parts of an array efficiently? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
EDIT: apparently I asked this question wrong. Before voting to close, please allow me to know what the question is missing. I promise you, this is not an unanswerable question. You can always come back and vote to close it later.
I'm currently working in C++, but I think this question applies to most compiled languages.
In my project, I have an array of values which are calculated individually, one at a time, as late as possible based off a single variable. These values are not all calculated at once, they are calculated if and only if they need to be. As is normally the case when using "dirty", the objective is to label certain things as being in need of update, without updating it preemptively. These values are cycled through over and over, so I'd like to cache the computation if possible. Whenever the single variable changes, all the values should be marked dirty so the cycle knows to recalculate before storing and moving on.
I can think of a few ways of achieving this, but I'm not sure what is most efficient:
Have two arrays, one of booleans and one of values. Mark all booleans to false if dirty, and true when clean.
Have a clean start point. Consider everything dirty until passing that cycle point again. Has the drawback of not allowing skipping of cycle entries.
Brand new array. Just create a new array, if any of the items are unset, set them. This one seems like it would have tons of problems, but it's a thought.
Perhaps use some built in class meant for this stuff?
The above are just the first things that came to mind for me, but I'm kind of new to c++ and would like to have some idea of normal or special solutions to marking an array dirty.
How can I dirty an array efficiently?
In order to show an example of code, I will show js which I'm more used to:
const numbers = [];
const clean = [];
let length = 1000;
let variable;
const setVariable(num) => {
variable = num;
for (let i = 0; i < length; i++) { clean[i] = false; }
}
setVariable(42);
let pos = 0;
while (true) {
if (clean[pos] == false) {
clean[pos] = true;
numbers[pos] = someIntensiveMath(pos, variable);
}
doSomethingWithNumbers(numbers[pos]);
pos++;
if (pos >= length) pos = 0;
// wait a bit;
}
in js you could also do
const setVariable(num) => {
variable = num;
numbers = [];
}
const isDirt = numbers[pos] === undefined;
With js the latter would probably be faster due to the native implementation of the script, but I don't think that's the case with compiled languages. I think you guys do things differently.
I've found elsewhere that the typical way to label entries of an array "dirty" is by having a parallel array of booleans.
#stark mentioned in the comments the idea of using a map, and speed comparisons of the two appear to be pretty decent, but it was advised in the following answer to use an array for indexed items.
performance of array vs. map
Whether or not changes in modern coding have led to a new defacto way of labeling items or parts of an array (or linear collection of items) as "dirty" is unknown. But in the very least, as an answer, the most straight forward nooby way is to have a parallel array of booleans.
Further, depending on the way you are iterating through the "array" it may make sense to use vector or map. In the case of either of those, the form of dirtying would probably be best done by clearing the map or removing vector entries(??).
So, to give my best answer, it would seem one should first find the storage method that best fits their needs, and then use whichever method is most normal for that.
For arrays, as this question was specified towards, parallel arrays appears to be the answer.

Implement the stack that pops the most frequently added item [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I was asked to implement a stack that pops the most frequently added item in an interview. I gave him the below answer but he was not happy with the solution.
class stack
{
// Map of value and count
map<int,int> Cntmap;
public:
void push(int val)
{
// Find val in map
// if found then increment map count
// else insert a pair (val,1)
}
int pop( )
{
// Find the Key in Cntmap with max value
// using std::max_element
// Decrement the Cntmap count for the popped val
}
}
Can anyone help me with the correct approach?
It's an interesting question, because in push, you look up
using the key, and in pop, using the mapped value. std::map
supports the first immediately: all you have to do is:
++ CntMap[ val ];
The [] operator will insert an entry if the key isn't
present, initializing the mapped type with its default
constructor, which for an int results in 0. You don't even
need the if.
The second is more difficult. The comments, however, give the
solution: all you need is a custom Compare, which takes two
std::pair<int, int>, and compares the second element.
std::max_element will return an iterator to the entry you're
interested in, so you can use it directly. So far so good (and
very simple), but you have to consider error conditions: what
happens if Cntmap is empty. And you might want to remove the
element if the count goes down to 0 (again, simple, since you
have an iterator designating the entry, with both the key and
the value).
Finally, if this is an interview question, I would definitly
point out that the pop operation is O(n), and that it might
be worthwhile (although significantly more complicated) to
maintain a secondary index, so that I could find the maximum
element more quickly. (If I were interviewing, that would be my
next question. Clearly for advanced programmers, however.)
The problem with only using a single (simple) data structure is that one of the operations will have to be linear (it has to search through all the elements), which is not good enough. In your case, I believe the linear-time operation is pop.
My attempt:
Have a linked-list (which will be ordered by frequency).
Have a map of values to nodes in the linked-list.
To push, look up the value in the map to get the linked-list node.
If found, increment the frequency and move the node appropriately to keep the linked-list sorted.
If not found, set the frequency to one and insert into the linked-list in the appropriate place.
To pop, decrement the frequency of first node of the linked-list and move it appropriately to keep the linked-list sorted, and return the applicable value.
You could have some pretty bad worst-case behaviour if there are many nodes with the same frequency. It should be possible to get constant time add / increment / decrement by having some sort of linked-list of linked-lists, with each node in the large linked-list representing a specific frequency and each linked-list from there representing all nodes having that frequency.
With the above optimization, pop can be O(1) and push can be O(log n). If you use an unordered_map (C++11), push can be O(1).
Another (probably slightly simpler) option is to do something similar to the above, but with a heap instead of a linked-list.
I think instead of a Map, Max-Heap will be better in your case. You can maintain a counter in a similar way. Note that the key of the heap will be the count rather than the actual value itself. When you have to insert a value, search for that value, if found, increment it's key, else, insert the value with key as 1.
Hope this helps.
The solution could be to wrap Boost.Bimap (does the organisation uses boost?). With this you could create a container which gives ordered access in one direction and hashed in the other. Your implementation of push and pop would use replace function of bimap.