java - 位移乘法循环

标签 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)值。我是否误解了位移位,或者循环中的某些东西是罪魁祸首?不确定还可以尝试什么。

最佳答案

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

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

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

32 == 25
4 == 22
1 == 20

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

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

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

关于java - 位移乘法循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12633240/

相关文章:

ruby - 在 ruby​​ 中,为什么数组追加在默认值为空数组的散列上失败?

java - 01001001的算术左移是什么?

java - 如何获取 Android 中当前的系统日期?

java - Android热敏打印机阿拉伯语问题

java - 链表排序方法在递归和比较列表中的元素时给出 StackOverFlow 错误

database - 在存储在数据库中之前用自己的 secret 加盐,有什么弱点?

c++ - 获取 C++ 类的字节表示

java - 为什么我的 Java Short 会被无符号右移的 1 填充?

c++ - C++ 中的移位运算符

java - Apache ftpserver 上传通知