if-statement - Elixir 二分查找

标签 if-statement binary-search elixir

我在 Elixir 中构建了一个二分搜索,但我最终使用了 3 个 if 子句:

if actual == guessed_number, do:

if actual > guessed_number do:

if actual < guessed_number do:

是否可以根本不使用条件?也许与模式匹配?

最佳答案

免责声明:不要在生产中使用它,这比简单的线性搜索慢,因为链表不允许在恒定时间内进行随机访问。这篇文章仅是关于模式匹配方面的。

理论上你可以使用保护子句,但如果你过度使用它们会使事情变得更糟。假设您从这样的实现开始:

defmodule MyEnum do
  def binsearch(collection, key) do
    binsearch(collection, key, 1, length(collection))
  end

  defp binsearch(collection, key, lo, hi) do
    if hi < lo do
      -1
    else
      mid = div(lo + hi, 2)
      item = Enum.at(collection, mid)
      cond do
        key < item -> binsearch(collection, key, lo, mid-1)
        key > item -> binsearch(collection, key, mid+1, hi)
        true       -> mid
      end
    end
  end
end

也许你想提取 if进入保护条款:
defmodule MyEnum do
  def binsearch(collection, key) do
    binsearch(collection, key, 1, length(collection))
  end

  defp binsearch(_collection, _key, lo, hi) when hi < lo do
    -1
  end

  defp binsearch(collection, key, lo, hi) do
    mid = div(lo + hi, 2)
    item = Enum.at(collection, mid)
    cond do
      key < item -> binsearch(collection, key, lo, mid-1)
      key > item -> binsearch(collection, key, mid+1, hi)
      true       -> mid
    end
  end
end

现在你也可以拉 condguard clauses但这并不是真正的改进:
defmodule MyEnum do
  def binsearch(collection, key) do
    binsearch(collection, key, 1, length(collection))
  end

  defp binsearch(_collection, _key, low, hi) when hi < low do
    -1
  end

  defp binsearch(collection, key, low, hi) do
    mid = div(low + hi, 2)
    item = Enum.at(collection, mid)
    binsearch(collection, key, item, low, mid, hi)
  end

  defp binsearch(collection, key, item, low, mid, _hi) when key < item do
    binsearch(collection, key, low, mid-1)
  end

  defp binsearch(collection, key, item, _low, mid, hi) when key > item do
    binsearch(collection, key, mid+1, hi)
  end

  defp binsearch(_collection, _key, _item, _low, mid, _hi) do
    mid
  end
end

关于if-statement - Elixir 二分查找,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27419231/

相关文章:

javascript - 使用 O(log n) 二进制搜索最接近值的索引/索引

java - 二维数组上的二进制搜索

websocket - 无法连接到 Phoenix 的网络套接字 : Ignoring unmatched topic. 但我认为它匹配

elixir - 如何在Elixir中打印出 map 的数组值?

c# - 如何在 if 语句之外使用已在 if 语句内声明的变量

java - Arrays.binarySearch 不能正常工作

java - 同一条线上的 if/else 条件不起作用

elixir - 如何在行为中使用 typespecs 和 Dialyzer?

c - 它总是第一个坦克

java - 决策和 if 方法