用于存储整数的HashMap替代方法

时间:2012-01-01 23:29:02

标签: java data-structures hash hashmap

我有一小组整数(大范围)。我需要能够在0(1)处查询此数据结构,并说明集合中是否存在整数。我目前正在使用Java& Colt OpenIntIntHashMap。 我有很多这些OpenIntIntHashMaps数据结构,每个包含5-15个整数。我大量查询。我只关心整数的存在 - 我不关心存储键的值。还有其他代表或更快的东西来帮助解决这个问题吗?

3 个答案:

答案 0 :(得分:4)

我担心我不是专家,但我认为很难实现真正的O(1)查找。但是,您可能希望查看某种完美的散列。如果这些集合较小,那么您可能有机会为它们生成“完美”散列函数 - 即它在集合中的项目之间不会发生冲突。这应该允许你进行O(1)查找 - 你取整数,哈希它,哈希将你带到一个地方,然后你做一个比较来检查整数是在集合内还是外面。您只需要检查一次,因为与不完美的哈希不同,没有冲突(在集合中的任何内容之间,内部和外部的事物可能会发生冲突),因此您只需要检查表中的一个单元格以查看是否存在整数集合。这应该是O(1)查找,但是计算这样的散列函数的成本可能很高,并且散列函数本身可能比通用散列函数昂贵得多(尽管仍然是O(1))。我根本没有在Java中使用它们的经验,但JPerf似乎有方法为任何类型的Java对象生成它们,我想你可以修改它以专门化为原始的int(JPerf是GPLv2)。

http://www.anarres.org/projects/jperf/

http://en.wikipedia.org/wiki/Hash_function#Minimal_perfect_hashing

答案 1 :(得分:2)

有10个数字,哈希集和树集大致相同 - 在我的旧机器上大约10 ^ 7。

import java.util.*;
public class Main {
    int n = 10;
    Random random = new Random();
    Set<Integer> hashSet = new HashSet<Integer>(n);
    Set<Integer> treeSet = new HashSet<Integer>(n);
    {
        List<Integer> numbers = new LinkedList<Integer>();
        for (int i = 0; i < n; i++)
            numbers.add(random.nextInt());
        System.out.println(numbers);
        hashSet.addAll(numbers);
        treeSet.addAll(numbers);
        System.out.println(numbers);
    }
    int hits, misses;
    void init() {

    }
    long time(Set<Integer> set, int n) {
        long t0 = System.currentTimeMillis();
        for (int i = 0; i < n; i++)
            if (set.contains(random.nextInt())) hits++;
            else
                misses++;
        return System.currentTimeMillis() - t0;
    }
    void print(long dt, int n, String set) {
        System.out.println(set + " " + n + " trials in " + dt + " ms. = " + 1000. * n / dt + "trials/sec.");
    }
    public static void main(String[] args) {
        int trials = 10000000;
        long dt=0;
        for (int i = 0; i < 10; i++) {
            Main main = new Main();
            dt = main.time(main.hashSet, trials);
            main.print(dt, trials, "hashSet");
            dt = main.time(main.treeSet, trials);
            main.print(dt, trials, "treeSet");
        }
    }
}

答案 2 :(得分:1)

如此小的“n”,我不会根据结构的复杂性做出决定;我会介绍一下,看看实际上最快的是什么。

Ο(log(n))算法可以比Ο(1)算法快,直到某个n值。 Ο符号只是告诉你算法如何缩放。事实上,如果你有很多这些地图,你可能会更担心空间效率。