例如,我们有一些范围 - 值对:
<<1, 2>, 65>
<<3, 37>, 75>
<<45, 159>, 12>
<<160, 200>, 23>
<<210, 255>, 121>
这些范围是不相交的。
给出一个整数78
,相应的范围为<45, 159>
,因此输出值12
。
由于范围可能非常大,我现在使用map
来存储这些范围 - 值对。
Evevy搜索将扫描整个地图集,它是O(n)
。
除了二元搜索之外还有什么好方法吗?
答案 0 :(得分:2)
二进制搜索绝对是您的最佳选择。 O(log n)很难被击败!
如果您不想手动编写二进制搜索代码,并且您正在使用C ++,则可以使用实现二进制搜索的std::map::upper_bound
函数:
std::map<std::pair<int, int>, int> my_map;
int val = 78; // value to search for
auto it = my_map.upper_bound(std::make_pair(val, val));
if(it != my_map.begin()) it--;
if(it->first.first <= val && it->first.second >= val) {
/* Found it, value is it->second */
} else {
/* Didn't find it */
}
保证 std::map::upper_bound
以对数时间运行,因为map
本身已经排序(通常实现为红黑树)。它返回你正在搜索的元素之后的元素,因此它返回的迭代器会递减以获得一个有用的迭代器。
答案 1 :(得分:0)
虽然您可能需要一个自我平衡的搜索树:AVL Trees和Red black trees are a good start,但您可能应该坚持使用您已经拥有的生态系统&#34;对于.Net来说可能是SortedDictionary,可能有一个成本IComparer,但这只是一个例子......
对于C ++,您应该使用有序地图,并使用自定义比较here
链接: http://en.wikipedia.org/wiki/Binary_search_tree http://en.wikipedia.org/wiki/AVL_tree http://en.wikipedia.org/wiki/Red-black_tree http://msdn.microsoft.com/en-us/library/f7fta44c%28v=vs.110%29.aspx http://msdn.microsoft.com/en-us/library/8ehhxeaf(v=vs.110).aspx http://www.cplusplus.com/reference/map/map/
对于C ++,我会做类似的事情(没有编译器,所以小心):
class Comparer
{
bool operator()(pair<int,int> const & one, pair<int,int> const & two)
{
if (a.second < b.first)
{
return true;
}
else
{
return false;
}
}
};
然后将地图定义为:
map<pair<int,int>,int,Comparer> myMap;
myMap.insert(make_pair(make_pair(-3,9),1));
int num = myMap[make_pair(7,7)]