Reputation: 4661
I have the following method written:
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;
}
I have been tasked with rewriting the for loop without using any multiplication or division. My only tools are addition and shifting of 16-bit binary numbers.
I realize that I need to somehow multiply hashVal by 37, and then add key.charAt(i) to this value. I have tried that multiple ways:
for(int i=0; i<key.length();i++) {
hashVal2 = hashVal2<<19 - hashVal2;
hashVal2 += key.charAt(i);
}
or
for(int i=0; i<key.length();i++) {
hashVal2 = hashVal2<<18 + hashVal2;
hashVal2 += key.charAt(i);
}
or
for(int i=0; i<key.length();i++) {
for(int j=0; j<37;j++) {
hashVal2 += hashVal2;
}
hashVal2 += key.charAt(i);
}
But none of these end up returning the same values for hashVal (or hashVal2) as the original method. Am I misunderstanding bit shifting, or is something with the loop the culprit? Not sure what else to try.
Upvotes: 0
Views: 1776
Reputation: 133
Left shift by 1 bit would multiply the number by 2. So to multiply by 37 convert 37 into binary. It would be 100101
Number * 2^5 + Number * 2^2 + Number * 2^0
Number << 5 + Number << 2 + Number
For loop would look like this:
for(int i=0; i<key.length();i++) {
hashVal = (hashVal << 5) + (hashVal << 2) + hashVal + key.charAt(i);
}
Upvotes: 1
Reputation: 234807
Multiplying by 37 is the same as adding certain powers of 2:
x * 37 == x * (32 + 4 + 1)
This tells you how to shift, since:
32 == 25
4 == 22
1 == 20
Finally, x * 2i == (x << i) for all i. So to multiply x by 37, you can compute
(x << 5) + (x << 2) + (x)
The rest of the exercise should be fairly straightforward.
Upvotes: 4