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同意-希望确保没有语言功能可以帮助处理这种类型的数据结构。