Efficient way to do std::map comparison based on their values - c++

I have two maps which I want to compare based on values. The maps are of type:
std::map<std::string, CustomMap> compareMap;
where CustomMap is:
std::map<std::string, Struct> CustomMap;
and Struct is a struct of two strings. This is how the design is and I can't change it.
How do I efficiently compare two compareMaps based on their values? The only way I can think of now is to use 2 for loops. Is there some inbuilt way to compare the maps based on their values? Or some way to calculate the hash on the values and find out which entries differ and which entries are the same?
EDIT: Let me rephrase my question: Is there a better elegant way to compare the maps based on their values instead of using two for-loops? I know the maps are different and some keys have the same values in both the maps. I only want to know which keys have different values in the two maps.
P.S: I don't have C++11

Related

Preferred data structure if you have two keys and can not use boost?

What data structure do you prefer if you have two keys, and can not use boost::multiindex?
I can have multiple records with Key1 and/or Key2 but there will be only one record for the combination of KEY1 KEY2.
My requirements are that I should be able to search
All the records for KEY1
All the records for KEY2
Single record given KEY1 and KEY2
Currently I am using std::map
std::map <CString, std::vector<CutomClass>> m_map;
the
So first key is used in map and another is part of my class (this class has more data alone with second key)
Is there any other data structure I can use instead?
I cant use boost library for some reason so I am looking for suggestion only from standard library.
The way I would implement this would be with three data structures. Two multi_map (or unordered_multimap), one keyed off KEY1, and another keyed of KEY2.
The third would me map (unordered_map) of KEY1 + KEY2 combination. For map, that would be simple and straightforward, for unordered_map, you'd have to combine the key, or, hash two subkeys and than combine the hash.
And I seem to forget to mention, only one of those maps (keyed of combined key) will hold actual values, two other maps will hold pointers to the values held in combined map.

What is the retrieval performance of tuple as values in a hashmap in Scala?

I have a hash map, using string as key, values are list of strings of size 2. I am trying to get the fastest performance time when getting the values back. The values will always contain only 2 strings. The question are:
what is the best container in this use case? List or Tuple?
What is the retrieval performance of tuple in Scala? is it equal to/faster than list?
By the way, I couldn't find anything on Scala tuple's performance. Please share if you know of any.
If you have a Tuple of two things, you will be using the case class Tuple2. As you can see, it is just a class that takes two parameters to instantiate.
If you're concerned about the performance of Lists versus Tuples, I suggest you write a benchmark. I find using ScalaMeter exceedingly useful when doing that. I suspect the performance of both will be the same.
If you're concerned about readability and reasonability of your code, I would suggest using a Tuple. If the values will always contain two values, then using Tuple2 is the better choice. Using a List implies that it could potentially contain less, or more, than two.

C++ data structure to perform indexed list

I am looking for the most efficient data structure to maintain an indexed list. You can easily view it interms of a STL map :
std::map<int,std::vector<int> > eff_ds;
I am using this as an example because I am currently using this setup. The operations that I would like to perform are :
Insert values based on key : similar to eff_ds[key].push_back(..);
Print the contents of the data structure in terms of each key.
I am also trying to use an unordered map and a forward list,
std::unordered_map<int,std::forward_list<int> > eff_ds;
Is this the best I could do in terms of time if I use C++ or are there other options ?
UPDATE:
I can do insertion either way - front/back as long as I do the same for all the keys. To make my problem more clear, consider the following:
At each iteration of my algorithm, I am going to have an external block give me a (key,value) - both of which are single integers - pair as an output. Of course, I will have to insert this value to the corresponding key. Also, at different iterations, the same key might be returned with different values. At the end my output data(written to a file) should look something like this:
k1: v1 v2 v3 v4
k2: v5 v6 v7
k3: v8
.
.
.
kn: vm
The number of these iterations are pretty large ~1m.
There are two dimensions to your problem:
What is the best container to use where you want to be able to look up the items in the container using a numeric key, with a large number of keys, and the keys are sparse
A numeric key might lend itself to a vector for this, however if the keys are sparsely populated that would waste a lot of memory.
Assuming you do not want to iterate through the keys in order (which you did not state as a requirement), then an unordered_map might be the best bet.
What is the best container for a list of numbers, allowing for insertion at either end and the ability to retrieve the list of numbers in order (the value type of the outer map)
The answer to this will depend on how frequently you want to insert elements at the front. If that is commonly occurring then you might want to consider a forward_list. If you are mainly inserting on the end then a vector would be lower overhead.
Based on your updated question, since you can limit yourself to adding the values to the end of the lists, and since you are not concerned with duplicate entries in the lists, I would recommend using std::unordered_map<int,vector<int> >

Map for one to many relationships

I need a data structure that can hold one to many relationship.
Some thing like a student can attend many courses. only thing is i might have it in order of thousands. one key to multiple values.
map<char,int> mymap; wont allow to insert same key again.
You can use std::multimap for this.
I would suggest this:
std::map<Student, std::vector<Course>> StudentInfos;
You just could use student id as key for faster comparison, or you could compare only id in operator< when comparing two instances of Student.
Use std::multimap<Key, T> and std::multimap<Key, T>::equal_range if it's okay to duplicate the key a lot. This is probably okay for integers and such.
If you want your key only once, as you will probably want for slightly more complex keys, such as std::string, use std::map<Key, std::vector<T>> and its find method.
The nested container is more appropriate for your example. The multimap is really only more appropriate if you have different keys that only "seem" identical respective your predicate.

Multiple keys Hash Table (unordered_map)

I need to use multiple keys(int type) to store and retrieve a single value from a hash table. I would use multiple key to index a single item. I need fast insertion and look up for the hash table. By the way, I am not allowed to use the Boost library in the implementation.
How could I do that?
If you mean that two ints form a single key then unordered_map<std::pair<int,int>, value_type>. If you want to index the same set of data by multiple keys then look at Boost.MultiIndex.
If the key to your container is comprised of the combination of multiple ints, you could use boost::tuple as your key, to encapsulate the ints without more work on your part. This holds provided your count of key int subcomponents is fixed.
Easiest way is probably to keep a map of pointers/indexes to the elements in a list.
A few more details are needed here though, do you need to support deletion? how are the elements setup? Can you use boost::shared pointers? (rather helpful if you need to support deletion)
I'm assuming that the value object in this case is large, or there is some other reason you can't simply duplicate values in a regular map.
If its always going to be a combination for retrieval.
Then its better to form a single compound key using multiple keys.
You can do this either
Storing the key as a concatenated string of ints like
(int1,int2,int3) => data
Using a higher data type like uint64_t where in u can add individual values to form a key
// Refer comment below for the approach