【问题标题】:Binary search in Erlang in lg(n) time在 lg(n) 时间内在 Erlang 中进行二进制搜索
【发布时间】:2010-09-08 22:26:18
【问题描述】:

我正在寻找在 Erlang 中进行二进制搜索的可能解决方法,我找到了 http://ruslanspivak.com/2007/08/15/my-erlang-binary-search/ 但我想知道博客中的解决方案是否在 O(lg n) 中运行。现在因为二分搜索的重复是:T(n) = T(n/2) + c 这给了我 O(lg n) 的执行时间。

由于在 C 数组中,您可以在 O(1) 时间内访问任何元素。但是在 erlang 中,如果访问列表的中间需要 cn 时间,那么二进制搜索的线性总体时间与线性搜索一样差。

我遇到了 lists:nth/2 BIF 用于查找列表中的第 n 个项目,但我不确定它的执行时间。

有没有cmets?

【问题讨论】:

    标签: erlang


    【解决方案1】:

    在 Erlang 中有一些数据结构允许 O(1) 访问:ETS 表、元组和二进制文件。

    现在,它们都不适合二进制搜索。 ETS 表支持从一开始就进行搜索,否则在返回结果时会将数据复制到您的进程中,这对于您的用例可能不是最佳的。

    元组允许使用 element/2 进行 O(1) 访问,但修改它们有一定的开销(这就是数组模块使用元组树的原因)。

    然后你有二进制文件(<<1,2,3,4,5>>),它允许类似于指针算术的东西,如下例所示:

    1> Sorted = <<$a,$b,$c,$d,$e,$f,$g,$h>>.
    <<"abcdefgh">>
    2> <<_:3/binary, X:1/binary, _/binary>> = Sorted.
    <<"abcdefgh">>
    3> X.
    <<"d">>
    

    但是,在构建二进制文件时预测性能有点粗略,如果您的值在二进制文件中表示时具有不同的类型和不同的大小,则这种指针算法更难进行。

    您最好的选择可能是使用一个值列表,对其进行排序,然后使用list_to_tuple/1element/2 在它周围导航。

    不过,我强烈建议您使用树进行搜索;使用 gb_tree 模块构建平衡树并仍然获得 O(log N) 搜索可能要简单得多。

    【讨论】:

      【解决方案2】:

      nth 是 O(n)。使用array module 进行常量访问数据结构(C 中的数组 - 几乎)。

      【讨论】:

      • 这是错误的。 Array 模块是一个非常扁平的元组树,分支因子约为 12,被选择为重写时间和访问时间之间的折衷。单个元素的访问时间仍然是 O(log N)。诸如 ETS 表之类的破坏性结构应该允许恒定时间访问,具体取决于表的数据和类型,但这增加了在表和任何 Erlang 进程之间进行复制的开销。否则,二进制 (&lt;&lt;"some_binary"&gt;&gt;) 可以允许看起来像指针算术的东西,并且元组也具有 O(1) 复杂性来访问数据。
      猜你喜欢
      • 2013-11-02
      • 2023-03-17
      • 1970-01-01
      • 2013-04-20
      • 2015-10-31
      • 1970-01-01
      • 2014-03-30
      • 2013-12-12
      • 1970-01-01
      相关资源
      最近更新 更多