【问题标题】:How to hash a range of numbers to a single position in the hash table如何将一系列数字散列到散列表中的单个位置
【发布时间】:2012-01-17 18:36:37
【问题描述】:

基本上,我有一个 2xN 整数到整数数组,它指示从哪个位置到对象位置的哪个位置。然后我有第二个整数数组,我想找到哪个整数落在哪个对象上。比如:

第一个数组

A:0 - 500

B:501 - 900

C: 901 - 1055

电话:1056 - 9955 等等

第二个数组: 1、999、3、898、55、43、1055、593、525、3099等

这应该返回 A、C、A、B、A、A、C、B、B、D 等。

我想弄清楚是否有一种方法可以使用一些散列函数来散列第一个数组,这样当散列第二个数组时,如果它落在对象的范围内,我会遇到冲突。任何想法如何做到这一点或如果可能的话?

谢谢!

【问题讨论】:

    标签: hashmap hashtable range hash


    【解决方案1】:

    您不能使用散列,但可以对区间端点进行排序并进行二等分搜索。

    类似这样的东西(在 python 中,但希望它对你有意义):

    endpoints = [501, 901, 1056, 9956]
    for x in [1, 999, 898, 55, 43, 1055, 593, 525, 3099]:
        print x, 'ABCD'[bisect.bisect_left(endpoints, x)]
    

    【讨论】:

    • 也许我应该多解释一下……但第一个数组实际上是一个流。所以我从一开始就没有所有的范围,只是太多了。我想要做的是检查第二个数组的索引 i 中的 int 是否已经存在于哈希图中。如果 int 在已经看到的范围内,则返回该对象,否则继续从流中读取,直到找到正确的范围(同时将我从流中读取的范围添加到哈希图中以备将来使用)。我知道我可以通过使用一棵树将其转换为 O(logn) ......但试图看看我是否不能做得更好。
    • 我不确定情况是否如此......如果范围是恒定的,那么这将是一个容易解决的问题......但是随着范围大小的改变,它会变得更加困难,但是我仍然不相信这是不可能的。
    • 数组使用的内存明显少于哈希图。此外,散列不能按您想要的方式工作:您不能散列一个区间,然后用它来测试一个点是否在其中。
    • 假设 hash(0) 是 K。然后考虑任何范围 [-N, N]。显然 0 在其中,所以它必须散列到相同的值。但是这个间隔中的每个点也必须散列到相同的值。结论是哈希函数必须是常数。
    • 我不确定你的教授是否有定论,如果 K 为零,那么我们可以轻松地划分一种将所有值散列为 0 的方法。如果我们简化这个问题并说我们知道范围的大小,那么它可以通过将位置四舍五入到最近的最大范围并对其进行散列来轻松解决......因此,如果我们有范围 [-N, N] 其中 N-(-N) = M,那么我们的散列是 min(i/米)。因此,能够对一个范围进行散列并不是不可能的。可能不可能的是对未知范围进行散列。但我不相信这一点。
    【解决方案2】:

    您的问题似乎与 BWT 解码密切相关。

    如果我正确理解了您的问题,您将收到第一个数组作为流。

    然后,如果您在内存中有第二个数组,您只需构建它的“反向数组”。因此,例如:

    第二个数组:1、9、3、8、5、4、2、6、7

    变成

    倒数第二个数组:1, 7, 3, 6, 5, 8, 9, 4, 2

    所以,现在,在接收到您的信息流后,您会立即知道每个字符的放置位置。

    【讨论】:

      【解决方案3】:

      您可以使用一些数据结构,如区间树来存储第一个数组。

      http://en.wikipedia.org/wiki/Interval_tree

      然后,当您遍历第二个数组时,您可以简单地查询树以获取匹配间隔。这样,您将需要 O(log n) 时间来查询第二个数组的每个元素。

      【讨论】:

        【解决方案4】:

        您可以使用NavigableMap

        示例代码:

        NavigableMap<Integer, String> map = new TreeMap<Integer, String>();
        map.put(0, "A");
        map.put(501, "B");
        map.put(901, "C");
        map.put(1056, "D");
        
        System.out.println(map.floorEntry(1).getValue());
        System.out.println(map.floorEntry(999).getValue());
        System.out.println(map.floorEntry(3).getValue());
        System.out.println(map.floorEntry(898).getValue());
        

        输出:

        一个 C 一种 乙

        【讨论】:

          猜你喜欢
          • 2013-05-16
          • 2016-09-04
          • 2010-09-26
          • 1970-01-01
          • 2013-04-07
          • 1970-01-01
          • 2013-07-08
          • 2011-12-25
          • 2012-02-21
          相关资源
          最近更新 更多