基于范围的数据结构的密钥查找

问题描述 投票:3回答:4

例如,如果我有以下场景

  1. 如果key的范围是1-4,则选择A.
  2. 如果key的范围是5-6,则选择B.

如果有一个请求获取say,key = 2的值,那么我应该返回A,为5,返回B,依此类推。保持这种关联的良好数据结构是什么?我可以通过存储1-A,2-A,3-A,4-A,5-B和6-B来创建哈希映射,但是想要检查是否有更好的方法来实现这一点。

data-structures
4个回答
2
投票

对范围内的每个项目使用哈希映射似乎过于宽泛,如果范围是(1-2 ^ 20)怎么办?如果它是一个双重怎么办?存储这些将太昂贵。

您可以使用普通的跳过列表/树,其中包括每个范围的下限和上限。请注意,当在二叉树中搜索某个值时,如果它不存在,搜索将在搜索之前/之后的下一个值处结束,例如:如果您有范围键1,4,则搜索3 ,当你达到1或4时,搜索将结束。所以我们可以在树中存储范围的上/下边界。

现在,我们还需要为这些中的每一个存储真实范围(所以如果我们有1-4,8-​​9并且我们搜索7,那么当我们达到4/8时我们就知道它无效)。因此,如果密钥在合法范围内,我们将在搜索时达到其上限/下限!

所以总之,只需添加下限和上限,在搜索时,搜索键,然后查看绑定是否匹配。

ops应该是那样的(伪代码):

add (lower,upper,value):
   tree.add(lower/*key*/,(lower,upper,value))
   tree.add(upper/*key*/,(lower,upper,value))
search (key):
   node = tree.search(key)
   if node.lower <= key <= node.upper: 
      return node.value
   return KEY_NOT_IN_TREE_ERROR
del(lower,upper):
  tree.del(lower)
  tree.del (upper)

这些操作中的每一个都是O(logn),慢于哈希,但它会消耗更少的空间。


1
投票

你可以创建成对的<interval,associated value>并构建segment tree。它可以在重叠间隔下正常工作。

如果间隔从不重叠,它仍然可以正常,因为分段树比基于散列的解决方案需要更少的内存。如果范围很宽,任何普通结构都需要大量内存。

编辑:我意识到,通常的矢量可以比哈希更适合你的目的,以防间隔彼此靠近。


1
投票

阿米特是对的。对于不重叠的范围,简单的有序数据结构就足够了。更清楚一点:

例如,按照最小边界对范围进行排序。搜索时,通过树进行闪电检查以查看您是否在您遍历的每个节点的范围内。


0
投票

最好使用类的对象作为hashmap的键存储。

在类中,您可以将Fields定义为上限,下限,并应覆盖equals和hashCode方法。

在equals中,您可以编写逻辑来比较密钥对象的upperbound和lowerbound在this.upperbound和this.lower bound之间。

要获取值,请使用相同的upperbound = lowerbound = key_val创建密钥对象;

© www.soinside.com 2019 - 2024. All rights reserved.