Data structures 将数值范围映射到具有O(1)访问权限的单个元素

Data structures 将数值范围映射到具有O(1)访问权限的单个元素,data-structures,mapping,range,big-o,Data Structures,Mapping,Range,Big O,问题很简单,我想把从0到N-1的每个数字映射到K0,{4,5,6,7}->1等等 我假设您已经在内存中的某个地方拥有来自原始数组/数据结构的数据。现在,您应该能够通过从映射计算数组索引(可能需要构建my_映射的反函数)来索引到它 索引的计算是O(1),您只使用原始数组中的空间 如果我误解了映射,很抱歉。嘿,是的,我理解你的意思,在这种情况下,间隔不是恒定的,因此以这种方式划分是不可行的。该问题类似于在K个元素之间进行加权抽签,每个元素具有不同的权重,权重之和为N,i,j,K,…,z为各个权重。

问题很简单,我想把从0到N-1的每个数字映射到K 注意:i,j,k,…,z是不同的值(否则我就不会使用不同的字母:)

有没有一种方法可以使结构和函数f(i)在时间O(1)中返回相应的元素,从而占据合理的空间量?(N个元素的向量,范围中的每个元素指向其影响的元素不是合理的空间量)

我能想到B树,它会给我一个O(log(n))访问时间,但我很好奇是否有一个O(1)有效的解决方案

提前谢谢


Bruno

如果i,k,…,z是任意的,那么就不会想到时间约束为O(1)且合理空间约束为折叠函数(i)!=折叠功能(i+1)

如果只频繁访问映射中的某些元素,还可以为映射构建缓存,从而导致缓存命中情况为O(1),缓存未命中情况为O(查找函数)。当然,缓存查找会影响每个元素花费的时间,即使是在缓存未命中的情况下,但不会影响算法的O复杂度

编辑 基本上,您想要实现的内容可以表示为带有集合作为标签的Pascal case语句:

case n of 
0..i-1:
  value:=0;
i..i+k-1:
  value:=1;
// ...
i+k+...+z+2..N-1:
  value:=K;
end
对于这个问题,谷歌搜索确实是一篇有趣的论文:

本文描述了一种建立静态搜索树的新方案, 使用多路基数搜索树。[…]对于稀疏情况,我们证明了这一点 设置时,该方法平均生成的代码比现有方法更快 方法,要求O(1)时间,平均值为一个小常数 搜索

Erlingsson,Krishnamoorthy,Raman:

唉,您没有稀疏的案例集,但就我所见,该算法应该只需要对具有大量连续结果的密集案例集进行最小的自适应


对于为case语句创建高效代码的一般问题,Zhao和Amarla有一个类似于使用缓存的方法。他们的论文在相关的工作部分也很有趣,这篇文章引用了Kannan和Proebsting的一篇论文(纠正为case语句生成好的代码),这篇论文需要O(n^2)设置集群时间。但是,我没有访问过这篇文章,听起来这只会产生一个非常优化的搜索树,因此导致运行时为O(log(n))。

如果我正确理解这个问题,您应该能够使用div mod直接计算映射。(见附件)

例如在python中

def my_map(n,k,i):
  elements_per_bin = n/k if n%k is 0 else n/k + 1  #in case n is exactly divisible by k
  return i/elements_per_bin    
例如,设n=10,k=3

>>> n=10
>>> k=3
>>> def f(i):
      return my_map(n,k,i)
>>> range(n)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> map(f,range(n))
[0, 0, 0, 0, 1, 1, 1, 1, 2, 2]
所以{0,1,2,3}->0,{4,5,6,7}->1等等

我假设您已经在内存中的某个地方拥有来自原始数组/数据结构的数据。现在,您应该能够通过从映射计算数组索引(可能需要构建my_映射的反函数)来索引到它

索引的计算是O(1),您只使用原始数组中的空间



如果我误解了映射,很抱歉。

嘿,是的,我理解你的意思,在这种情况下,间隔不是恒定的,因此以这种方式划分是不可行的。该问题类似于在K个元素之间进行加权抽签,每个元素具有不同的权重,权重之和为N,i,j,K,…,z为各个权重。当然他们不一样。你的答案很好:)但它不适用于这个具体问题。到目前为止,我很想相信同样的答案(即:没有具有“小”空间约束的O(1)算法)。如果没有人能给出一个好的答案,我会把你的作为一个正确的答案。很好的答案!非常有用的纸张!谢谢