Data structures 散列函数溢出
在我的数据结构类中,我们正在学习不同的哈希函数,但我不明白为什么在代码的最后三行中,他们检查HashValHashVal是否为int,它是否具有最大大小。 如果字符串的长度足够长,hashVal会变得非常大,因为您多次将其乘以37,它就会溢出。 当它溢出时,可能会变成负数,因此需要检查hashVal是否为负数 还有一种已知的方法可以解决这个问题。 改变Data structures 散列函数溢出,data-structures,hash,Data Structures,Hash,在我的数据结构类中,我们正在学习不同的哈希函数,但我不明白为什么在代码的最后三行中,他们检查HashValHashVal是否为int,它是否具有最大大小。 如果字符串的长度足够长,hashVal会变得非常大,因为您多次将其乘以37,它就会溢出。 当它溢出时,可能会变成负数,因此需要检查hashVal是否为负数 还有一种已知的方法可以解决这个问题。 改变 for(int i=0;i
for(int i=0;i
进入
for(int i=0;i
hashVal是一个int,它有一个最大大小。
如果字符串的长度足够长,hashVal会变得非常大,因为您多次将其乘以37,它就会溢出。
当它溢出时,可能会变成负数,因此需要检查hashVal是否为负数
还有一种已知的方法可以解决这个问题。
改变
for(int i=0;i
进入
for(int i=0;i
Java中的int已签名。所以,它可以存储的最大值是Integer类中的常量。基于(左位是符号位)一旦一个数字超过最大值,它将根据该表示变成负数。Java中的int是有符号的。所以,它可以存储的最大值是Integer类中的常量。基于(左位是符号位)一旦一个数字超过最大值,它将根据该表示变成负数。hashVal是一个int,它可能会溢出变成负数。hashVal是一个int,它可能会溢出变成负数。非常感谢您的回答!按照您更改for循环的方式,不必检查溢出,对吗?在for循环中使用long可能会有所帮助。我猜如果表大小足够大,模块结果*37可能仍然会溢出。顺便说一句,@Artem的答案描述了整数溢出的原因。非常感谢您的回答!按照您更改for循环的方式,不必检查溢出,对吗?在for循环中使用long可能会有所帮助。我猜如果表大小足够大,模块结果*37可能仍然会溢出。顺便说一句,@Artem的答案描述了整数溢出的原因。
public static int hash(String key, int tableSize)
{
int hashVal = 0;
for( int i = 0; i < key.length(); i++ )
hashVal = 37 * hashVal + key.charAt(i);
hashVal %= tableSize;
if( hashVal < 0 ) //overflow case
hashVal += tableSize;
return hashVal;
for( int i = 0; i < key.length(); i++ )
hashVal = 37 * hashVal + key.charAt(i);
hashVal %= tableSize;
for( int i = 0; i < key.length(); i++ ) {
hashVal = 37 * hashVal + key.charAt(i);
hashVal %= tableSize;
}