Assume I have a nested map of type pointer. Then is there a single line statement to insert into the nested map,
map<int, map<int, int> >* nestedMap;
Currently I am doing this in 2 steps. First creating innermap and then insert into outer map as below,
nestedMap->insert(make_pair(int, map<int, int>)(int, innermap));
If the map is not pointer type, then i can insert easily like this,
nestedMap[int][int] = int;
Is there any simple ways for inserting into nested map of type pointer ?
thanks
Prabu
map::operator[] automatically creates the key/value pair if it doesn't exist.
(That's why it's not const!)
So you don't need to create the inner map manually.
If you want to avoid creating the pair automatically, then use map::find() or map::at().
I believe the simplest one-liner is:
(*nestedMap)[int][int] = int;
If i understand your question properly, you can actually use reference instead of pointer. You are not having issue with nested map, instead your outter map.
See below code, is what you want?
map<int, map<int, int> >* nestedMap = new map<int, map<int, int> >;
map<int, map<int, int> > &nestedMapAlais = *nestedMap;
nestedMapAlais[1][2] = 3;
access the operator[] via ->:
nestedMap->operator[](5)[6] = 7;
This is analogous to
nestedMap[5][6] = 7;
if nestedMap is not a pointer.
Note that in neither case do you have to explicitly insert a map.
Related
c++
map<int, vector>* maxcounts;
When I have a pointer to map maxcount how do I write this next statement correctly?
maxcounts[-m.second]->push_back(m.first);
without referencing a pointer I write
maxcounts[-m.second].push_back(m.first);
map<int, vector<char>> maxcounts;
for (pair<char, int> m : counts) {
if (maxcounts.count(-m.second))
maxcounts[-m.second].push_back(m.first);
else
maxcounts.insert({ -m.second, {m.first} });
}
To figure out how to use a pointer to the map, first rewrite your loop this way:
std::map<char, int> counts;
//...
std::map<int, std::vector<char>> maxcounts;
for (std::pair<char, int> m : counts)
maxcounts.insert({-m.second, std::vector<char>()}).first->second.push_back(m.first);
Note that the return value for std::map::insert is a std::pair, where the first of the pair is an iterator to the existing item if the item already is in the map, or the iterator to the newly inserted item. Thus you can perform the test and insert in one line without need for an if statement.
The push_back will occur, regardless of whether the item inserted in the map is new or if the item existed. Note that for a new entry, the std::vector being inserted starts as empty.
Given this, the pointer to the map version is very simple:
std::map<char, int> counts;
//...
map<int, vector<char>>* maxcounts;
//
for (pair<char, int> m : counts)
maxcounts->insert({-m.second, std::vector<char>()}).first->second.push_back(m.first);
Now, why you need a pointer to a map in the first place is another issue, but to answer your question, the above should work.
I would likely write something like:
std::map<int, std::vector<int>>* maxcounts = ...;
for (std::pair<char, int> m : counts)
(*maxcounts)[-m.second].push_back(m.first);
I'm trying to make my code 1 line shorter, a noble cause. I have this unordered map
std::unordered_map<std::string, int> um;
and I want to assign the integer to a variable on the same line where I emplace a pair into the unordered map like so
int i_want_132_here = um.emplace("hi", 132).first.???;
problem is, I have no idea what to do with [return value of unordered_map::emplace].first
In the debugger I can see that "first" contains ("hi", 132) but how do I access those values?
emplace returns a pair<iterator, bool>.
So you should do:
int i_want_132_here = (*um.emplace("hi", 132).first).second;
alternative syntax:
int i_want_132_here = um.emplace("hi", 132).first->second;
In general I prefer (*it) form instead of it->.
I'm trying to implement a 2D unordered_map that looks like:
std::unordered_map<std::string, std::unordered_map<std::string, double>>
So first, I implemented the inner unordered_graph by doing:
std::unordered_map<std::string, std::unordered_map<std::string, double> *inner = new
std::unordered_map<std::string, std::unordered_map<std::string, double>>()
inner->insert(std::make_pair("X", 0));
Then, I tried to make the outer unordered_map by doing
std::unordered_map<std::string, std::unordered_map<std::string, double> *outer =
std::unordered_map<std::string, std::unordered_map<std::string, double>>()
outer->insert("X", inner);
but it gives me an error saying thatno matching function for call to insert
You're using insert wrong here:
outer->insert("X", inner);
It expects a value_type i.e. std::pair. You're passing two arguments instead of one, so you need to do make_pair() on those arguments, plus you need to pass a value, so *inner instead of inner which is a pointer.
Once this is all said and done, you will probably be better off with a different data structure, as a hash table of hash tables is usually not the most efficient.
If I have a std::multimap<int, std::map<int, MyClass>> myMultimap how to I insert a class object MyClassA into the map with value 1 at multimap value 2?
It looks like I can do myMultimap.at(2).insert(std::pair<1,MyClassA>); in c++11 but I am using c++98 due to a library regression/incomparability out of my control.
I've also tried
myMultimap[2].insert(
std::make_pair(
myMultimap[2].end(),
myClassA
)
);
which gives: error: no match for ‘operator[]’ (operand types are ‘std::multimap<int, std::map<int, ns_namespace::MyClassType> >’ and ‘int’)| for both of the [...]'s.
I don't want to do something like myMultimap.insert(std::make_pair(2,std::make_pair(1,MyClassA)))
because if I understand correctly, this would make a new map in the multimap rather than assigning the class object to the existing map within the multimap.
It is a two stage process:
Locate the position in the outer map where you want to do something to the inber map. If necessary, insert a new element.
Update the inner map withthe appropriatevalue.
I don't know why the outer map us a multimap (they are rarely useful) so the exampke just uses the first entry:
auto it = mymultimap.lower_bound(2);
if (it == mymultimap.end() || it->first != 2) {
it = mymultimap.insert(
std::make_pair(2, std::map<int, MyClass>())).first;
}
(*it)[1] = MyClassA;
(typed on a mobile device: there are probably typos but the overall approach should work).
I have a vector of pairs, which is empty at the beginning. I implemented a custom insert and remove method, and I would also like to be able to assign NULL to certain elements, but I can't because it's not a pointer to pair.
If I try to illustrate it more specifically - given a vector V
std::vector< std::pair<A,B> > V;
neither
V.assign(number,NULL);
nor
V[n]=NULL;
would work.
I need to do this to check if there already is an element saved in a certain slot. Is there anywork around or should I just create another vector of booleans to save wheter a certian slot is full or not?
NOTE: I know any kind of map would solve it elegantly, but it has to be a vector.
I think solution with map would be optimal in your case:
std::map<int, std::pair<A, B> > M;
Then you can do
M.erase(M.find(number))
To NULL-ify to the element.
If I had to do it I would do something like
vector< pair< pair<A,B> ,int > >V , V[i].second can be 0 or 1 depending whether the element
pair has to be NULL or not.This if if you want to mark the pair NULL but still keep it for refernece.Otherwise use map as Alex1985 said.
I advise you to look at boost::optional
boost::optional< std::vector< std::pair<A,B> > > V;
if (V) {
// V was initialized
} else {
// wasn't initialized
}
documentation examples: http://www.boost.org/doc/libs/1_54_0/libs/optional/doc/html/boost_optional/examples.html
Use shared_ptr as the second type in the pair.
std::vector< std::pair<A,std::shared_ptr<B> > > V;
V.assign(number, std::shared_ptr<B>());
V[n] = std::shared_ptr<B>();
V[n] = std::shared_ptr<B>(new B());
if (V[n].get() == NULL) { /* process empty here */ }
The shared_ptr class was introduced to C++ in TR1, and is part of the C++11 specification. It works well with standard containers because it