繁体   English   中英

Elixir中最有效的间隔类型搜索

[英]Most efficient interval type search in Elixir

我从Elixir开始我的旅程,并且正在寻找有关如何最好地解决特定问题的建议。

我有一个需要尽快搜索的数据集。 数据由两个数字组成,这些数字形成一个封闭的带以及与每个带关联的一些元数据。

例如:

From,To,Data    
10000,10999,MetaData1
11000,11999,MetaData2
12000,12499,MetaData3
12500,12999,MetaData4

该数据集最多可以有100,000个条目。

我定义了一个对数据进行建模的struct ,以及一个用于创建Elixir列表内存表示形式的解析器。

defmodule Band do
    defstruct from: 0, to: 0, metadata: 0
end

解析器返回Band struct的列表。 我定义了一个使用列表推导的find方法

defp find_metadata(bands, number) do
        match? = fn(x) -> x.from <= number and x.to >= number end

        [match | _ ] = for band <- bands, match?.(band), do: band

        { :find, band }
end

根据我的新手知识,使用列表理解将需要完整遍历列表。 为了避免扫描整个列表,我使用了其他语言的搜索树。

Elixir中是否有可用的算法/机制/方法可以更有效地解决此类搜索问题?

谢谢。

如果带是互斥的,你可以构建他们到排序树from 搜索那棵树应该花费log(n)时间。 类似于以下内容的东西应该起作用:

defmodule Tree do
  defstruct left: nil, right: nil, key: nil, value: nil

  def empty do
    nil
  end

  def insert(tree, value = {key, _}) do
    cond do
      tree == nil    -> %Tree{left: empty, right: empty, key: key, value: value}
      key < tree.key -> %{tree | left: insert(tree.left, value)}
      true           -> %{tree | right: insert(tree.right, value)}
    end
  end

  def find_interval(tree, value) do
    cond do
      tree == nil                -> nil
      value < tree.key           -> find_interval(tree.left, value)
      between(tree.value, value) -> tree.value
      true                       -> find_interval(tree.right, value)
    end
  end

  def between({left, right}, value) do
    value >= left and value <= right
  end
end

请注意,您也可以使用Ranges来存储“带”,即所谓的“带”。 另请注意,树不平衡。 一种(可能)实现平衡树的简单方案是在插入间隔之前先对其进行混洗。 否则,您将需要一个更复杂的实现来平衡树。 您可以查看erlang的gb_trees以获得灵感。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM