【问题标题】:Looking for a generic `bisect` function寻找一个通用的 `bisect` 函数
【发布时间】:2012-03-24 22:42:33
【问题描述】:

我正在寻找类似于 Python 的 bisect_left() 和朋友的 Haskell 中的 bisect 操作。输入将是一个下限、一个上限、一个非递减函数 (Ord a)=>(Int->a) 必须为下限和上限之间的所有整数定义,以及一个搜索值。返回值是最大整数i,其中lower <= i <= upperf(i) < search_term。性能应该是 O(log(n))。

为此进行搜索:

(Ord a)=>(Int->a)->Int->Int->a->Int

不会产生任何结果。

在某处的库中是否有标准、通用的二分搜索运算符?

【问题讨论】:

  • Int -> a 函数是否假定为单调递增/非递减?
  • @jwodder 函数应该是非递减的 -- 编辑添加约束
  • 您可能还喜欢手指树,它旨在高效搜索单调谓词。

标签: haskell


【解决方案1】:

Ross Paterson 在 Hackage 上的 binary-search 包可以满足您的需求。具体看searchFromTo,有类型签名

searchFromTo :: Integral a => (a -> Bool) -> a -> a -> Maybe a

正如 Tikhon 所指出的,Haskell 中的[a] 是一个链表,而不是一个数组。由于链表仅支持顺序访问,因此无法对 [a] 数据结构进行对数时间搜索。相反,您应该使用真正的数组数据结构——请参阅vector 库以了解数组的首选实现。

Dan Doel 为 vector 包中的 mutable 向量编写了一系列二分搜索函数:请参阅他的 vector-algorithms 库中的 Data.Vector.Algorithms.Search。与提供纯 API 的 Ross Paterson 库相比,Data.Vector.Algorithms.Search 中的 API 是单子的(即,它必须在 ST monad 或 IO monad 中运行)。

【讨论】:

    【解决方案2】:

    bisect_left 这样的函数(假设我正确阅读了它的文档)对于列表来说实际上是不存在的。

    这是有道理的——因为您在 O(1) 的列表中没有随机访问权限(请记住,Haskell 列表是 链表,而 Python 使用更像向量的东西),您无法真正获得 O(logn) 二进制搜索。

    特别是,仅仅到达列表的中间需要 O(n/2) (这只是 O(n)) 步骤,因此涉及列表中间的算法(如二进制搜索)必须是Ω(n)。

    简而言之-- 列表 上的二进制搜索没有意义。如果您进行大量搜索,您可能需要不同的数据结构。特别是看一下Data.Set,它内部使用了二叉树。

    【讨论】:

    • @monadic 但他的类型签名表示列表。他的术语很混乱。
    • @bitbucket 确实——太多的 C 编程让我将 [] 与“数组”这个词联系起来,我很草率。然而,我真正在寻找的是一种适用于任何非递减函数的二进制搜索,而不仅仅是排序列表或数组。所以我删掉了关于 Lists / Arrays 的句子,因为它们只是混淆了这个问题。
    【解决方案3】:
    binary_search :: Ord a, Integral b => (b -> a) -> b -> b -> a -> b
    binary_search f low hi a = go low hi
         where
            go low hi | low + 1 == hi = low
            go low hi = go low' hi'
               where
                  mid = (low + hi) `div` 2
                  (low',hi') = if f mid < a then (mid,hi) else (low, mid)
    

    (这可能有一个错误。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-19
      • 2021-05-21
      • 2012-07-26
      • 2016-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多