基于基数的自定义哈希函数

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于基数的自定义哈希函数相关的知识,希望对你有一定的参考价值。

我想开发一个哈希函数,它接收一个BitSet对象,并根据BitSet中的1的数量生成哈希值。该数字使用以下公式计算:

BitSet b = new Bitset();
int card = b.cardinality();

例如:

110
1
010
111

我想要一个按此顺序返回元素的Map:

1
010
110
111

要么

010
1
110
111

我尝试使用TObjectIntCustomHashMap的解决方案:

map = new TObjectIntCustomHashMap<BitSet>( new HashingStrategy<BitSet>() {
            @Override
            public int computeHashCode( BitSet str ) {
                return System.identityHashCode( str );
            }

            @Override
            public boolean equals( BitSet str1, BitSet str2 ) {
                return (str1.cardinality() < str2.cardinality());
            }
        });

但结果并不像预期的那样。

答案

我认为从user93335240构建的最干净的解决方案是将自定义比较器应用于TreeSet,允许像这样的O(nlogn)解决方案:

Set<Integer> t = new TreeSet<>((a, b) -> { a.cardinality() - b.cardinality() });
t.forEach((a) -> System.out.println(a));

您可以在哪里创建自己的包装器以提供cardinality()功能。

您不能使用散列,因为它不保证在发生冲突时分配hashCode值。您可以尝试线性探测之类的东西,但不保证它是正确的。

事实上,如果你得到一个sub disproving the lower bound on the comparison sort based model解决方案,这将是O(nlogn)

另一答案

回答你,即使我认为@MathBunny是对的......最好使用专用的结构来处理你的需求,而不是使用hashmap的当前实现的副作用...这里是你搜索的

public class HashTest {
    public static class BitSet extends java.util.BitSet {

        private static final long serialVersionUID = 4014851086683360760L;

        public BitSet(int i) {
            super(i);
        }

        public BitSet() {
            super();
        }

        @Override
        public int hashCode() {
            return stream().map(i -> (int) Math.pow(2, i)).sum();
        }

        @Override
        public boolean equals(Object obj) {
            if (obj instanceof java.util.BitSet) {
                return obj == null ? false : obj.hashCode() == hashCode();
            } else {
                return false;
            }
        }
    }

//  1
//  010
//  110
//  111
    public static void main(String[] args) {
        BitSet bitset1 = new BitSet(1);
        bitset1.set(0);
        BitSet bitset2 = new BitSet(3);
        bitset2.set(1);
        BitSet bitset3 = new BitSet(3);
        bitset3.set(1);
        bitset3.set(2);
        BitSet bitset4 = new BitSet(3);
        bitset4.set(0);
        bitset4.set(1);
        bitset4.set(2);
        Map<BitSet, String> map = new HashMap<>();
        map.put(bitset1, "bitset1");
        map.put(bitset2, "bitset2");
        map.put(bitset3, "bitset3");
        map.put(bitset4, "bitset4");
        map.forEach((k, v) -> System.out.println(v));

    }

}

以上是关于基于基数的自定义哈希函数的主要内容,如果未能解决你的问题,请参考以下文章

PagerSlidingTabStrip- 使用列表片段的自定义视图显示突然的行为

基数排序

如何在 Shader 图形的自定义函数中使用 TEXCOORD0?

在 rabin-karp 滚动哈希中选择基数和模素数

GLSL:找不到我的自定义函数

片段内的自定义列表不起作用