0

I have a multiset mymulti where I sort according to a class member m_a.

I want then to check for all sorted elements, if the difference in m_a for neighbour fields of mymulti is less than my given threshold, say 0.001. If so, then I want to prefer that which has a smaller another class member, m_b.

Here I am stuck, I have no experience with multiset or iterators. I don't know how to compare iterators from two iterations. If you can provide me with a right code for this what I want to do, will be very grateful! My try, not too much, just my concept:

    //all before I got stuck
    for(it = mymulti.begin(); it!= mymulti.end(); ++it) //or it++?
        if( (it+1)->mymulti.m_a - (it)->mymulti.m_a < 0.001)
           if ((it+1)->mymulti.m_b < (it)->mymulti.m_b)
              //swap them. but how to swap two fields in a multiset, not two multisets?
           // otherwise do nothing
eddie
  • 1,252
  • 3
  • 15
  • 20
josh130
  • 305
  • 1
  • 5
  • 12
  • 3
    Don't make floating point variables into a key for sets... – Kerrek SB Jan 28 '13 at 14:59
  • I have no other choice, why shouldn't I, because of calculation time? anyway it is already working, I just want to add this 'inner second' sorting inside .. – josh130 Jan 28 '13 at 15:02
  • @eReM Because floating-point numbers are approximations and don't reliably equal each other when directly compared. For example, `0.1 * 10.0`, `1.0`, and `0.1 + 0.1 + 0.1 ...` may all equal different values. See http://www.altdevblogaday.com/2012/02/22/comparing-floating-point-numbers-2012-edition/ – Matt Kline Jan 28 '13 at 15:06
  • Also, what if you saturate your set with elements that are all 0.001 apart, from 0 to 1000. Does that mean that 0 and 1000 are the same? – Kerrek SB Jan 28 '13 at 15:11
  • @Kerrek SB I have to rely here later on unlikelihood, algorithmic is not important, thanks for this tipp though. So lets say I want just to check first two elements. How to do it properly? – josh130 Jan 28 '13 at 15:16

1 Answers1

0

You cannot (or if you can, depending on your STL implementation, should not) modify items once they have been inserted into a multiset, as it could violate the provided ordering of the items in the multiset. So swapping would be a bad idea, even if you could do it.

See https://stackoverflow.com/a/2038534/713961 and http://www.cplusplus.com/reference/set/multiset/

If you would like to remove items, use multiset::erase, which takes an iterator. I believe the standard practice for "modifying" an item in a multiset is to remove it, then insert the modified version.

As a side note, I noticed you're checking if two floating point numbers are close enough in value by using a fixed epsilon (0.001). As explained in this article, this only works if all the floats you are comparing are sufficiently small. See the article for a comparison that works equally well for large and small floating-point values.

Community
  • 1
  • 1
Matt Kline
  • 10,149
  • 7
  • 50
  • 87
  • if you wanted to sort according to 2 parameters, one with higher priority, and the second with lower priority in case the first parameter would be the same for a couple of fields in multiset, how would you do it then? – josh130 Jan 28 '13 at 15:21
  • @eReM If I didn't want items to have the same value for the sake of ordering, I would use a `set` instead of a `multiset` (`set`s don't allow for identically-valued items). If you want to sort using two priorities, all of the ordered associative containers (`map`, `set`, `multiset`, etc.) can take a custom comparator function (see http://en.cppreference.com/w/cpp/container/set/set) that sorts items however you want. – Matt Kline Jan 28 '13 at 15:28
  • 1
    thanks for a tipp! the right idea here will be I think to change the comparator function instead of adding code after the first sorting. – josh130 Jan 28 '13 at 15:30