Skip to content

Instantly share code, notes, and snippets.

@lallousx86
Last active July 6, 2017 01:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lallousx86/27e494fba4b06014ec7c29b00bebd5df to your computer and use it in GitHub Desktop.
Save lallousx86/27e494fba4b06014ec7c29b00bebd5df to your computer and use it in GitHub Desktop.
find_range() using lower_bound of std::map(). The underlying mapped type should implement both is() and contains()
// Test std::map's lower_bound()
#include <stdio.h>
#include <map>
#include <iostream>
struct range_t
{
unsigned long a;
unsigned long b;
bool contains(unsigned long x)
{
return x >= a && x <= b;
}
bool is(unsigned long k)
{
return k == a;
}
};
typedef std::map<unsigned long, range_t *> range_lookup_t;
range_t test_items[] =
{
{ 5, 8 },
{ 10, 12 },
{ 14, 18 },
{ 22, 26 }
};
//-------------------------------------------------------------------------
template <class _MAP> bool find_range(
_MAP &m,
typename _MAP::key_type key,
typename _MAP::mapped_type &found)
{
// Return an entry whose key is not less than the search key
auto lb = m.lower_bound(key);
auto _end = m.end();
// Two cases:
// 1. No key greater then fk
// 2. Did not find the exact key
if (lb == _end || !lb->second->is(key) )
{
if (lb == m.begin())
return false;
// Check the previous element
--lb;
if (lb == _end || !lb->second->contains(key))
return false;
}
found = (lb->second);
return true;
}
//-------------------------------------------------------------------------
int main()
{
// Convert to map
range_lookup_t lookup;
for (auto &item : test_items)
lookup[item.a] = &item;
auto items_end = std::end(lookup);
unsigned long fk;
while (true)
{
std::cin >> fk;
if (fk == 0)
break;
range_t *item;
bool ok = find_range(lookup, fk, item);
if (ok)
{
printf("%d - %d\n",
item->a,
item->b);
}
else
{
printf("not found!\n");
}
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment