I am looking for something like a school time table. Based on two input - Day of the week and Time of the day, one decides the subject. To implement this in c++, I was thinking of something like "map < pair < int, int>, int>".
I was reading here to use a key class and operator overloading.
Is there any other elegant way of doing it?
Thanks in Advance
That's not a map with two keys (which would allow you to look up items from knowledge of just one key), it's a composite key, and map<pair<day, time>, subject> should work just fine.
Also consider map<day, map<time, subject>>.
You could typedef it.
typedef pair<int, int> key;
map<key, int> myMap = new map<key, int>();
You can't create a map with 2 key values, you can create a map with a complex key value (composed of two types). However, this won't let you look at the map for say just day of week regardless of time of day. I would create a new class to use as key, and some helper functions to be able to work by just day or just time.
Also, for your use case Boost.MultiIndex may help you.
Related
There is a great example of a simple hash table in C++ for a single key, but I would like to hash on a <int, double> combination so that, for example h[5, 0.1] will return a double. Is this possible?
One possible method to get around this is to create an array of unordered_maps, and then have the key be a double. So, for example, I could simply call h[5][0.1] and get the double value back. In this the best way to go about this or can I create a multi-variabled key?
Sure. Make your key std::pair<int, double> (or tuple of <int, double>). Define appropriate hashing function (I would say hash(int) ^ hash(double) might work)
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.
I need to insert values into std::map (or it's equivalent) to any free position and then get it's key (to remove/modify later). Something like:
std::map<int, std::string> myMap;
const int key = myMap.insert("hello");
Is it possibly to do so with std::map or is there some appropriate container for that?
Thank you.
In addition to using a set, you can keep a list of allocated (or free)
keys, and find a new key before inserting. For a map indexed by
int, you can simply take the last element, and increment its key. But
I rather think I'd go with a simple std::vector; if deletion isn't
supported, you can do something simple like:
int key = myVector.size();
myVector.push_back( newEntry );
If you need to support deletions, then using a vector of some sort of
"maybe" type (boost::optional, etc.—you probably already have
one in your toolbox, maybe under the name of Fallible or Maybe) might be
appropriate. Depending on use patterns (number of deletions compared to
total entries, etc.), you may want to search the vector in order to
reuse entries. If your really ambitious, you could keep a bitmap of the
free entries, setting a bit each time you delete and entry, and
resetting it whenever you reuse the space.
You can add object to an std::set, and then later put the whole set into a map. But no, you can't put a value into a map without a key.
The closest thing to what you're trying to do is probably
myMap[myMap.size()] = "some string";
The only advantage this has over std::set is that you can pass the integer indexes around to other modules without them needing to know the type of std::set<Foo>::iterator or similar.
It is impossible. Such an operation would require intricate knowledge of the key type to know which keys are available. For example, std::map would have to increment int values for int maps or append to strings for string maps.
You could use a std::set and drop keying altogether.
If you want to achieve something similar to automatically generated primary keys in SQL databases than you can maintain a counter and use it to generate a unique key. But perhaps std::set is what you really need.
I have a problem with the creation of a hash of arrays. I need a Single Key - Multi Data system:
multimap <Type, vector<type> > var;
But how I can add elements to the vector?
Example: key = 3;
Now I need to append some elements into the vector whose key is 3.
Creating a temp-vector not an answer because I don't know when I need to input element into the vector with the current key.
sorry, understand my problem. i need fast-access struct, that will be operate with ~50,000 words with length ~20 each.
and i need something like tree.
also, have question:
how quick STL-structures, like vector,map,multimap and other?
What's wrong with std::map <KeyType, std::vector<SomeType> >, or some other collection as the value type? This gives you control over how to operate on the value collection. A multimap to me seems like a low-level form of std::map <KeyType, std::list<SomeType> >, but with none of the flexibility of a list.
To find the answer to your question you can look at the slides under point 6. at this site https://ece.uwaterloo.ca/~ece250/Lectures/Slides/
Hope that helps!
I have some data with a key associated with each data item. The key is made of two parts: let's call them color and id. I want to iterate the container by color to speed up rendering and I also want to find items in the container by id alone.
I tried using std::map for this with a key
class MyKey {
public:
int color;
int id;
bool operator<(...)
bool operator==(...)
};
But I cannot provide a < operator that would keep the data sorted by color and at the same time allow map::find to work on id alone (i.e. no information about color).
I want both the insert and find operations to be fast (e.g. O(log(n))).
Any ideas what kind of container I could use to implement this?
Adapt the example here from Boost.Multi_index based on the following modifications:
typedef multi_index_container<
MyKey,
indexed_by<ordered_unique<identity<MyKey> >,
ordered_non_unique<member<MyKey,int,&MyKey::color> >
>
> DataSet;
Try Boost.BiMap, it's a map with 2 views.
Otherwise there is the more complicated Boost.MultiIndex.
If you'd rather write your own than use Boost (dumb in my opinion) you can make a class that holds two maps. One to map color and the other to map ID. The map values would be pointers. You'd define insert and find operations for your new class. The insert would new a data struct and insert the pointer into both maps. The find operations would locate the item using either map as appropriate. For delete/remove operations it is a little trickier: you'd need to look up the data struct by a map, then remove it from both maps, probably by using the data in the data struct to find the other map entry.