Urgent! How to control iterator of multimap

Hi,

I am running some simulation, in which i need to control the iterator of a multimap, like
1
2
3
4
5
6
7
8
multimap<double, int> mapp;
......

int n=6;
for(int i=0; i<5; i++) {
   for(auto it = mapp.begin()+i*n; it!=mapp.begin()+(i+1)*n; it++) {
      ......

However this way of controlling is not possible for multimap. Could someone pleasae tell me why and how the make it work?
Do I need to overload the operator +?
Thanks a lot!

Last edited on
Do I need to overload the operator +?
No. But would help if you explained what you're trying to do.
Could someone pleasae tell me why and how the make it work?


You can't make this work. Maps don't have random access iterators.

What are you trying to accomplish exactly?
I create a multimap object to contain a series of objects with two values, as its special feature. the first element (key) is double, second element is int, int =0 or 1 or 2.

Then I have to check in a certain range of this multimap the number of objects with their ".second" element = 0, and number of objects with their ".second" element =1, ...

The range here in my example is 1/6 of total number of objects in this multimap. That means if there are 48 objects in the multimap, I check from 0-7, then 8-15, then 16-23, ... and for each part I have checked I collect results.
Last edited on
Or do you know what kind of technique I can use to store objects of two element (one double, one int), and I can sort the order of these objects according to one element (the double one, for example), and to get access only to a part of these objects...

It is for a special statistical usage...
Thanks a lot!
Any of the following may prove useful:

http://www.cplusplus.com/reference/algorithm/upper_bound/
http://www.cplusplus.com/reference/algorithm/lower_bound/
http://www.cplusplus.com/reference/algorithm/equal_range/

If you're iterating through the map in chunks, you may consider keeping an iterator to one past the last element processed and begin from there next time you start processing. If the map contents change between times, that may not work out well, though.

If this usage is typical, you might want to consider using a vector in lieu of a map.
A multimap is sorted by key order. So, it's already sorted by double in your case.

The range here in my example is 1/6 of total number of objects in this multimap. That means if there are 48 objects in the multimap, I check from 0-7, then 8-15, then 16-23, ...
1
2
3
4
5
6
7
8
9
10
11
12
13
size_t block_size = 6;
size_t nblocks = mapp.size() / block_size;

std::multimap<double, int>::iterator p = mapp.begin();
for (size_t i = 0; i != nblocks; ++i)
{
    for (size_t j = 0; j != block_size; ++j)
    {
        std::pair<double, int> &value = *p;  // do something with it!

        ++p;   // should be in inner for statement, but put here for clarity
    }
}
Last edited on
To cire: thanks for your rapid reply. I checked quickly the links. It seems those three "tools" return iterator according to value. But here in my case I have to control the iterator by number of elements in the multimap.
Because here each object has two elements (double and int) I am not sure if I can store them in a vector...

To kbw: Thanks for the proposition. Could you just explain what is the meaning of the code, please?
1
2
std::pair<double, int> &value = *p;
++p; 

Do you mean by &value I can check whether the second element of each object is =0, for example?
p is an iterator into the collection mapp.
*p is the element pointed to, and that element is a std::pair<double, int>.

The statement std::pair<double, int> &value = *p; is just a reference to that element. You can use value and *p interchangeably. Of course, if you don't use value, you don't need the declaration. But I think it's nicer and clearer when you use value rather than *p.

You need ++p to get to the next element in the collection. Rewriting it without the teaching aids:
1
2
3
4
5
6
7
8
9
10
11
12
const size_t block_size = 6;
const size_t nblocks = mapp.size() / block_size;
assert(nblocks*block_size == mapp.size());

std::multimap<double, int>::iterator p = mapp.begin();
for (size_t i = 0; i != nblocks; ++i)
{
    for (size_t j = 0; j != block_size; ++j, ++p)
    {
        // handle each element here
    }
}
Last edited on
It works! Thanks kbw! I think the elements that make it work is to declare the iterator outside of loop so it will hold its position after each loop, and to add a j to limit to increment of the iterator.

Btw, why did you use size_t for i and j? int is not a good type?
A container size is of type size_t, not int. A size_t is an unsigned value.

You should set up your compiler such that you're warned when they're mixed.
Last edited on
But here in my case I have to control the iterator by number of elements in the multimap. Because here each object has two elements (double and int) I am not sure if I can store them in a vector...


Of course you can store them in a vector.

std::vector<std::pair<double,int>> v;

would be one way to do it.
Thanks kbw and cire for your answers.

So we can save objects of two elements in vector or map. Which container is better? In terms of speed and security, for example?

Moreover, if I want to save objects of several elements (3 elements or more, type of double or int), and I need to be capable to sort them according to one element. How can I do it? struct?
So we can save objects of two elements in vector or map
You can store whatever you like in STL containers.

Which container is better? In terms of speed and security, for example?
It depends on your requirements.

if I want to save objects of several elements (3 elements or more, type of double or int), and I need to be capable to sort them according to one element.
You could use a sorted container, like a set.
Thanks kbw for your answer. Could you please give me an example about how to save objects (each one has 3 elements of double type for example ) in a set container?
Topic archived. No new replies allowed.