如何快速搜索范围巨大的值对?

时间:2014-06-22 16:25:34

标签: algorithm search range

例如,我们有一些范围 - 值对:

<<1, 2>, 65>
<<3, 37>, 75>
<<45, 159>, 12>
<<160, 200>, 23>
<<210, 255>, 121>

这些范围是不相交的。

给出一个整数78,相应的范围为<45, 159>,因此输出值12

由于范围可能非常大,我现在使用map来存储这些范围 - 值对。 Evevy搜索将扫描整个地图集,它是O(n)

除了二元搜索之外还有什么好方法吗?

2 个答案:

答案 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)

Binary search tree怎么样?

虽然您可能需要一个自我平衡的搜索树:AVL TreesRed 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)]