Reputation: 2989
Just as we can initialize vectors as:
vector<int> var1(2000,1);
Is it possible to initialize map;
map<int, int>var2;
for 2000 variables...the reason why I want to initialize are two:
Is there some way by which I can initialize the map for say 1000 variables...I am also open to using any other data structure.
Also the conventional way of initializing map i.e.
map<int, int> m = map_list_of (1,2) (3,4) (5,6) (7,8);
The above way does not work in my case...is there some other way out.PLEASE HELP
EDIT: I can not use for loop as:
This way the key remains fixed which I don't want since the distribution of my keys is skewed. In essence applying for loop in this way is the same as that of vector and this I don't want
Upvotes: 3
Views: 1684
Reputation: 208323
You don't need to do anything at all. When you use operator[]
to access a key that was not previously inserted, a new value is created, initialized to 0 and a reference returned. There is no need to initialize at all.
Also nNote, that when you insert elements into the map, the key is fixed, so if you decide to insert 100 elements, the keys will be fixed, which will make initialization useless in most use cases.
I would avoid the complexity of initializing the map, and rather have a helper function that replaces operator[]
as:
int &getValue( std::map<int,int>& m, int key ) {
return *m.insert( std::make_pair(key,1) ).first;
}
There is no need to preallocate the nodes. The trick is that insert
is equivalent to a lookup if the value already exists in the map, but will add the element if it was not present. Attempting an insert of a pair<int,int>(key,1)
will insert 1
into the container if it did not exist before, but will leave the value untouched if it was already there. Because insert
returns an iterator, we can use that to obtain a reference into the stored value.
The use would be just as simple as access through operator[]
:
int x = getValue( mymap, 31 ); // 1 if 31 was not present in the map, else
// the value stored there.
getValue(mymap,31) = 5; // Ugly, I know... but still simpler than providing
// an extra type, and preinitializing the container
Upvotes: 0
Reputation: 726509
You can do it using a surrogate instead of an int
in your map, like this:
#include <iostream>
#include <map>
using namespace std;
struct surrogate_int {
int val;
surrogate_int() : val(1) {}
surrogate_int& operator=(const int v) { val=v; }
operator const int() { return val; }
};
int main() {
map<int,surrogate_int> m;
m[5] = 5;
m[7] = 7;
m[9] = 9;
for (int i = 0 ; i != 10 ; i++) {
cout << i << ":" << m[i] << endl;
}
return 0;
}
Upvotes: 1
Reputation: 1179
boost::assign:
///from http://www.boost.org/doc/libs/1_35_0/libs/assign/doc/index.html
#include <boost/assign/list_inserter.hpp> // for 'insert()'
#include <boost/assert.hpp>
#include <string>
using namespace std;
using namespace boost::assign; // bring 'insert()' into scope
{
map<string,int> months;
insert( months )
( "january", 31 )( "february", 28 )
( "march", 31 )( "april", 30 )
( "may", 31 )( "june", 30 )
( "july", 31 )( "august", 31 )
( "september", 30 )( "october", 31 )
( "november", 30 )( "december", 31 );
BOOST_ASSERT( months.size() == 12 );
BOOST_ASSERT( months["january"] == 31 );
}
Upvotes: 0
Reputation: 181
You probably want to define your own data type that has an embedded priority (defaulting to 0, presumably), and define a comparator that uses that priority to order objects of your type. Something like
class MyType {
int val;
int priority;
MyType(int val, int priority = 0): val(val), priority(priority) {}
bool operator<(MyType const& other) { return priority < other.priority; }
}
Then you can just make a priority queue of that type, avoiding using a map at all.
Upvotes: 0
Reputation: 28762
You can do the old fashied way of using loops:
map<int, int> var2;
for (int = 0; i < 1000; ++i) {
var2[i] = 0;
}
On the other hand usign the subscript notation (var2[x]
) will add the value with its default value (0 for int
) if the key does not exist in the map yet.
Upvotes: 0