位移乘法循环

时间:2012-09-28 03:32:32

标签: java hash bit-shift

我写了以下方法:

public static int hash2(String key, int tableSize) {
    int hashVal = 0;

    for(int i=0; i<key.length();i++) {
        hashVal = 37 * hashVal + key.charAt(i);
    }

    System.out.println(hashVal);

    hashVal %= tableSize;   
    if(hashVal < 0){
        hashVal += tableSize;
    }

    return hashVal;
}

我的任务是重写for循环而不使用任何乘法或除法。我唯一的工具是添加和移位16位二进制数。

我意识到我需要以某种方式将hashVal乘以37,然后将key.charAt(i)添加到此值。我尝试过多种方式:

    for(int i=0; i<key.length();i++) {
        hashVal2 = hashVal2<<19 - hashVal2;
        hashVal2 += key.charAt(i);
    }

    for(int i=0; i<key.length();i++) {
        hashVal2 = hashVal2<<18 + hashVal2;
        hashVal2 += key.charAt(i);
    }

    for(int i=0; i<key.length();i++) {
        for(int j=0; j<37;j++) {
            hashVal2 += hashVal2;
        }
        hashVal2 += key.charAt(i);
    }

但是这些都不会像原始方法那样返回hashVal(或hashVal2)的相同值。我是否误解了位移,或者是循环的罪魁祸首?不知道还有什么可以尝试。

2 个答案:

答案 0 :(得分:4)

乘以37与添加2的某些幂相同:

x * 37 == x * (32 + 4 + 1)

这告诉你如何转移,因为:

  

32 == 2 5
  4 == 2 2
  1 == 2 0

最后,对于所有i,x * 2 i ==(x <&lt; i)。因此,要将x乘以37​​,您可以计算

(x << 5) + (x << 2) + (x)

其余的练习应该相当简单。

答案 1 :(得分:1)

左移1位会将数字乘以2。 所以乘以37将37转换成二进制。这将是100101

Number * 2^5 + Number * 2^2 + Number * 2^0
Number << 5 + Number << 2 + Number 

For循环看起来像这样:

for(int i=0; i<key.length();i++) {
    hashVal = (hashVal << 5) + (hashVal << 2) + hashVal + key.charAt(i);
}