Search Elixir中最有效的区间类型搜索

Search Elixir中最有效的区间类型搜索,search,list-comprehension,elixir,Search,List Comprehension,Elixir,我正在用长生不老药开始我的旅程,我正在寻找一些关于如何最好地解决一个特定问题的建议 我有一个需要尽快搜索的数据集。数据由两个数字组成,形成一个封闭的频带和一些与每个频带相关的元数据 例如: From,To,Data 10000,10999,MetaData1 11000,11999,MetaData2 12000,12499,MetaData3 12500,12999,MetaData4 此数据集最多可以有100000个条目 我定义了一个对数据建模的struct,以及一个在内存表示中创

我正在用长生不老药开始我的旅程,我正在寻找一些关于如何最好地解决一个特定问题的建议

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

例如:

From,To,Data    
10000,10999,MetaData1
11000,11999,MetaData2
12000,12499,MetaData3
12500,12999,MetaData4
此数据集最多可以有100000个条目

我定义了一个对数据建模的
struct
,以及一个在内存表示中创建长生不老药列表的解析器

defmodule Band do
    defstruct from: 0, to: 0, metadata: 0
end
解析器返回
结构的列表
。我定义了一个使用列表理解的
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
defp find_元数据(波段、编号)do
匹配?=fn(x)->x.from=编号结束

[match |(u]=对于波段如果波段相互排斥,您可以将它们组织成一棵树,按
排序。在该树中搜索应该花费
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
defmodule-Tree-do
defstruct left:nil,right:nil,key:nil,value:nil
def空do
无
结束
def insert(树,值={key,})do
康多
tree==nil->%tree{left:empty,right:empty,key:key,value:value}
key%{tree | left:插入(tree.left,value)}
true->%{tree | right:insert(tree.right,value)}
结束
结束
def查找间隔(树,值)do
康多
树==nil->nil
value查找间隔(tree.left,value)
介于(tree.value,value)->tree.value之间
true->查找间隔(tree.right,value)
结束
结束
def介于({left,right},value)do之间

value>=left和value由于间隔似乎形成了一个连续体,并且数据被排序,我认为搜索值大于或等于下限的第一个条目就足够了。换句话说,存储上界并比较
值我认为这是不正确的-这样一个节点的右子树可能包含间隔,间隔的
,仍然小于
。特别是考虑一个只有间隔<代码> { 1, 10 } /代码>和<代码> { 11, 20 } /代码> -查找15不正确地停止在<代码> { 1, 10 } /代码>,搜索100,在任一个区间停止是不正确的。谢谢大家,我将实现树数据结构,看看结果如何。@ ObROK你是对的。人们必须寻找第一个不符合要求的条目,然后将前一个条目作为结果。但是,如果值超过最后一个间隔,仍然会产生错误的结果。Enum.find/2很可能是您想要的(它将遍历一个列表,直到您找到与给定谓词/函数匹配的第一个)。感谢@JoséValim,我很担心顺序搜索的时间。在20K的搜索空间中,运行5000次搜索,并在搜索空间的末尾进行匹配,列表理解需要约1400ms,而Enum.Find则需要约1800ms。我使用了
混合测试--trace
来获取时间-不确定这是否足够准确?在某种程度上(正如下面@obrok所建议的),这不是一个灵丹妙药问题,而是一个数据结构问题。选择正确的数据结构,您的性能应该会非常好。@Onriocatenacci同意-希望确保没有语言功能可以帮助处理这种类型的数据结构。