3

Can someone suggest an elegant way to solve the following problem please?

I have a multi-map keyed by time, and i wish to return the item that occured closest to a specified time T. In addition, the times searched within the map can only be an hour either side of T.

Tried multiple techniques, however the most efficient would seem to be to firstly reject all times that are not within an hour of T, and then iterate over the remaining items to find the one closest to T.

pingu
  • 8,719
  • 12
  • 50
  • 84

2 Answers2

9

Just use map.lower_bound() to find the first time that isn't lower than the one you are looking for, then just check the adjacent (smaller) if it's closer than the one returned by lower_bound() and you are done.

Šimon Tóth
  • 35,456
  • 20
  • 106
  • 151
  • Actually, I think the "check adjacent" step must be done iteratively while the difference with the actual time *T* stops decreasing. – Fred Foo Jan 05 '12 at 12:45
  • @larsmans: Can you elaborate? Since a multimap is ordered, `T` is between `lower_bound - 1` and `lower_bound`, I don't see how it could be closer from another key. Or perhaps you mean that since we're dealing with a multimap, there could be several items that are closest to `T`? – Luc Touraille Jan 05 '12 at 13:07
  • @LucTouraille: thinko on my part. Never mind, +1 to Let Me Be. – Fred Foo Jan 05 '12 at 13:09
  • @LucTouraille Even in a multimap you need to check only one, since, the `lower_bound` returns the first that isn't smaller, so you just need to check the one that was still smaller. – Šimon Tóth Jan 05 '12 at 13:09
  • Yes, you only need to check `lower_bound` and `lower_bound - 1` to find the closest key, but this key can be associated with several values; that's what I meant in my question to @larsmans. – Luc Touraille Jan 05 '12 at 13:12
0

How about trying to find an entry with the exact time first. If not found, then check for time + 1, then time - 1, then time + 2, etc. until you reach the limit of one hour from the time.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621