Create a hash map without original key values - c++

I have a file containing a list of couples. Each couple contains a 64 bit integer, that is an hash computed over a string, and a value that is an integer.
I want to load the list in a hash map in the main memory.
And then search values using the original string (I have the hash function).
For Example the file could be like:
keys values
78243536 12
38735342 20
32353498 18
if I want to search a term for example "pippo" I can use hashfunction("pippo").
The question is: can I use std::map computed on these hash? How can I insert directly the hash values inside the map without having the original string?

A map is a mapping between keys of a given type and values. The interface of the map is defined in a way that you may either iterate through the whole map or search for a specific element using the key in the map. In your case you want to be able to search not by a key in the map but using another element that is somehow relevant to this key. You can not do this with bare map but you can create a helper function to handle that for you:
map<long long, int> my_map;
.... so some stuff ...
map<long long, int>::iterator find_by_string(const std::string& s) {
return my_map.find(hash_code(s));
}

Hashing operation is irreversible (multiple strings can have the same hash value), so hash value cannot be used as a unique key and what you are trying to do is not possible.

Related

Inserting into Map of String keys and Vector values

I'm a smidge rusty on using map and need a lil' help; I've declared the below.
std::map<std::string, std::vector<double>> myMap;
I'm periodically reading JSON data, where the ordering of data may sometimes change, or new data elements appear. Other parts of my code will loop through the JSON and extract two variables (jsonLabel, a string), and the associated value as a double (latestDouble).
If jsonLabel already exists, I want to add the associated latestDouble to the end of the vector; if it doesn't exist, make the new Key and start a vector.
I've tried the below; however I keep crashing. I'm presuming it's because map actually isn't smart enough to insert latestDouble at the end of the vector in the map.
myMap.insert(std::make_pair(jsonLabel, latestDouble));
Pseudo Example:
JSON parse #1: [A,43],[B,10],[C,9]
JSON parse #2: [A,10],[C,4],[B,3] /// Change in ordering
JSON parse #2: [A,8],[B,7],[C,2],[D,1] /// New element
Should result in:
A: 43,10,8
B: 10,3,7
C: 9,4,2
D: 1
Thanks for any help!
If the string in jsonLabel already exists as a key in the map, then insert will not insert anything into the map.
And the map insert function is to insert into the map itself. The pair should be a pair of the key and value types (where the value should be a vector of doubles).
What you seem to want is simply
myMap[jsonLabel].push_back(latestDouble);
The operator[] function will create a default-constructed value if the key doesn't exist, and as such will create an empty vector for you.

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.

Check if element exist or not

I have a multimap.
std::multimap<CString, CString> NameInsituteMap;
and I have to write function which return true if both name and institute matches otherwise false;
bool InsituteExist( const CString Name, const CString Insitute )
{
}
I can find the key and iterate all the value to compare if Institute exist or not.
I want to know if there is any direct way of doing that instead of looping through all the element and comparing.
I am open to use any other data structure than multimap if that makes things nicer.
Use equal_range from multimap.
Here you have a live example
You can find the sequence elements from the multimap for a given key efficiently. There is no better way to find a particular value from this sequence, than linear search.
std::map<CString, std::set<CString>> would be an alternative data structure, which is also efficient for finding whether a value exists in the set associated with the key. It has a bit different interface though. Instead of simply inserting a value to a key, you must "get" the value set of a key, insert into that set.
If the map aspect of your data structure isn't used otherwise, another simpler alternative is to use std::set<std::pair<CString, Cstring>>. This can be easily used to test if the key-value pair is in the set, but of course lacks other features that the multimap had.

Dictionary in C++ using a Map with no values, only keys

I'm implementing some sort of lookup for words in c++, and while the code for implementing a map is there, I wanna make sure if it works that using a map with keys and values as std::string, and using only keys as lookups without a value to return.
std::vector< std::string> DictionLines;
Reader DictionReader(Dictionary);
DictionLines = DictionReader.getLines();
std::map<std::string, std::string> DictionaryM;
for (int t = 0; t < DictionLines.size(); ++t) {
DictionaryM.insert(std::pair<std::string, std::string>(DictionLines.at(t), DictionLines.at(t)));
}
This code takes in the 349900 words in a Dictionary.txt file, and stores them in the map. Each line of the dictionary is just the word to lookup; no definition or any value to associate. Which is why I think just storing a pair of the same key and value in the map is ok, and using find and first/second would also be fine? Please confirm.
It looks like you want std::set. It is like a map where only keys matter and you never care or use the value. To look in a dictionary represented as a std::set<std::string> for some word after a given prefix, consider lower_bound
You should look more into C++ standard containers. There are not that much choice, and you should somehow know all of them (and choose or combine the right containers for the job)

How to sort a map with its maximum value of key in C++

I am trying to sort a map with definition map<double,deque<Object>>
with the maximum value of double (key) but by default the map takes the minimum value of key . How can I sort the map by the maximum value of key which is a double .
Thanks in advance
You can't re-sort a map, but you can use a map that sorts itself in the reverse order to the default. std::map has a third template parameter for the comparison functor used for ordering. The default is std::less<key_type>. You can trivially use the reverse ordering by using std::greater<key_type>:
std::map<double, std::deque<Object>, std::greater<double>> m;
The closest you can come to sorting a map is to create a new one based on an original with different sorting criteria:
std::map<double, std::deque<Object>> orig = ....;
std::map<double, std::deque<Object>, std::greater<double>> m(orig.begin, orig.end());
map is a key-value pair, key has to be unique in general, if not then value type could be a vector or list instead of a single typed elemental value like hash_map> where MyType is struct or a class. While querying you search with the key to retrieve the value, no notion of sorting. Otherwise, you need to use a vector instead.