是否有可用于Java的算法,这将允许我继续添加String对象并删除旧对象,这样如果我添加了String
然后将其删除,整数哈希将是相同的?
编辑:哈希中的字符串是唯一的。
一些伪代码:
h = hash
add(h, "hi!") == 51;
add(h, "hello again!") == 532;
rem(h, "hello again!") == 51;
我知道你可以使用Java集合来实现它,但默认实现必须继续遍历整个集合以收集哈希码。这对于大型集合来说效率非常低。我不介意使用外部库(如果存在)。
提前致谢,
克里斯
答案 0 :(得分:2)
如果你不关心哈希算法是否具有加密质量(加密哈希算法很难正确指定;你搞砸了,有人可能会在你不希望它们时引起冲突),下面应该工作:
请考虑以下代码:
interface Accumulator<T, U>
{
public void add(T t);
public void subtract(T t);
public U get();
}
class SumHasher implements Accumulator<String,Integer>
{
@Override private int accumulator = 0;
@Override public void add(String t) { accumulator += t.hashCode(); }
@Override public void subtract(String t) { accumulator -= t.hashCode(); }
@Override public Integer get() { return accumulator; }
}
class XorHasher implements Accumulator<String,Integer>
{
@Override private int accumulator = 0;
@Override public void add(String t) { accumulator ^= t.hashCode(); }
@Override public void subtract(String t) { accumulator ^= t.hashCode(); }
@Override public Integer get() { return accumulator; }
}
这些共同点是加法和XOR都是关联并且反转的操作。您可以按任意顺序执行它们并按任意顺序撤消它们,这样,如果add()
中的每个元素Set<T>
,则subtract()
中的每个元素都会(x << k) | (x >>> (32-k))
(不一定是相同的顺序),保证你得到0。
肯定有其他操作可以满足这个属性,但我不确定它们是什么。 (乘法不起作用,除非你能保证所累积的项目都没有值为0.这个答案过去常用f(x,h)=((x ^ h)+ h)^ h和g(x,h )=((x ^ h) - h)^ h作为反转,但这些函数不是关联的:以不同的顺序累积元素会产生不同的结果。
编辑:我 想到另一个简单的:基于输入值的按位置换(其中按位旋转是一种特殊情况)。在Java中,您可以使用糟糕,只有在set以相反的顺序删除。x
实现按位旋转,其中>>>
是一个整数,k是0到31之间的整数(例如,从另一个数字中获取任意5位)。 >>
不是一个错字:您需要使用它,因为常规abstract class AbstractHashCodeAccumulator<T> implements Accumulator<T, Integer>
{
private int accumulator = 0;
abstract protected int combine(int a, int h);
abstract protected int uncombine(int a, int h);
@Override public void add(T t) { accumulator = combine(accumulator, t.hashCode());
@Override public void subtract(T t) { accumulator = uncombine(accumulator, t.hashCode());
@Override public Integer get() { return accumulator; }
}
class SumHasher extends AbstractHashCodeAccumulator<String>
{
@Override protected int combine(int a, int h) { return a+h; }
@Override protected int uncombine(int a, int h) { return a-h; }
}
class XorHasher extends AbstractHashCodeAccumulator<String>
{
@Override protected int combine(int a, int h) { return a^h; }
@Override protected int uncombine(int a, int h) { return a^h; }
}
会执行符号扩展。
编辑2 :最后,您可以更一般地实施此方法,如下所示:
{{1}}
这种方法的问题在于,它在某些方面是“非散列的”,即它需要有序性,而散列通常需要无序/熵/不可逆性。