Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/387.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 散列到负值_Java_Hash - Fatal编程技术网

Java 散列到负值

Java 散列到负值,java,hash,Java,Hash,差不多就是标题:我正在散列一堆名字(10000个左右),其中一些以负数输出。(表大小为20011) 所讨论的哈希函数是: public static long hash2 ( String key ){ int hashVal = 0; for( int i = 0; i < key.length(); i++ ) hashVal = (37 * hashVal) + key.charAt(i); return hashVal % 20011; } 公共静态长

差不多就是标题:我正在散列一堆名字(10000个左右),其中一些以负数输出。(表大小为20011)

所讨论的哈希函数是:

public static long hash2 ( String key ){
  int hashVal = 0;
    for( int i = 0; i < key.length(); i++ )
      hashVal = (37 * hashVal) + key.charAt(i);
  return hashVal % 20011;
}
公共静态长哈希2(字符串键){
int hashVal=0;
对于(int i=0;i

我四处寻找,我想我必须做些与“环绕”有关的事情。但我不知道该怎么做

这是一个明显的
整数溢出
。正如您在问题中提到的,字符串最多可以包含
10000
个字符,那么
hashValue
肯定会溢出,因为需要在
37^10000
附近存储值。即使这样,长度为
20
的字符串也会失败

在数论中

(A+B)%M = (A%M + B%M) % M;
(A*B)%M = (A%M * B%M) % M;
您应该在for循环中应用模运算。然而,如果您在最后或在for循环的执行中执行模运算,如果没有发生溢出,这两种方法将给出相同的答案

所以要做相应的修改,

public static long hash2 ( String key ){
  int hashVal = 0;
    for( int i = 0; i < key.length(); i++ )
    {
      hashVal = (37 * hashVal) + key.charAt(i);
      hashVal%=20011;
    }
  return hashVal;
}
公共静态长哈希2(字符串键){
int hashVal=0;
对于(int i=0;i
这是一个明显的
整数溢出案例。正如您在问题中提到的,字符串最多可以包含
10000
个字符,那么
hashValue
肯定会溢出,因为需要在
37^10000
附近存储值。即使这样,长度为
20
的字符串也会失败

在数论中

(A+B)%M = (A%M + B%M) % M;
(A*B)%M = (A%M * B%M) % M;
您应该在for循环中应用模运算。然而,如果您在最后或在for循环的执行中执行模运算,如果没有发生溢出,这两种方法将给出相同的答案

所以要做相应的修改,

public static long hash2 ( String key ){
  int hashVal = 0;
    for( int i = 0; i < key.length(); i++ )
    {
      hashVal = (37 * hashVal) + key.charAt(i);
      hashVal%=20011;
    }
  return hashVal;
}
公共静态长哈希2(字符串键){
int hashVal=0;
对于(int i=0;i
hashVal
是一个整数。您的哈希函数很可能导致整数溢出

通过使用
Math.abs()
确保
hashVal
为正数,可以轻松解决此问题。e、 g

hashVal = hashVal == Integer.MIN_VALUE ? 0 : Math.abs(hashVal);
return hashVal % 20011;

mod
%
用于确保计算的最终索引在表的范围内(即,如果大于等于20011,则使用除法的剩余部分作为“环绕”)。

hashVal
是一个整数。您的哈希函数很可能导致整数溢出

通过使用
Math.abs()
确保
hashVal
为正数,可以轻松解决此问题。e、 g

hashVal = hashVal == Integer.MIN_VALUE ? 0 : Math.abs(hashVal);
return hashVal % 20011;

mod
%
用于确保计算的最终索引在表的范围内(即,如果大于等于20011,则使用除法的剩余部分作为“环绕”)。

如果不确定是否为“环绕”,则使用
Math.toIntExact
。如果是这样的话,这应该抛出一个异常。另外,考虑到您的方法返回类型是
long
为什么不将
hashVal
声明为long呢?既然您定义了
hash2()
来返回
long
,为什么要将
int
用于
hashVal
?在那里也使用
long
。如果您不确定它是否为“环绕”,请使用
Math.toIntExact
。如果是这样的话,这应该抛出一个异常。另外,考虑到您的方法返回类型是
long
为什么不将
hashVal
声明为long呢?既然您定义了
hash2()
来返回
long
,为什么要将
int
用于
hashVal
?在那里也使用
long
。注意
Math.abs(Integer.MIN_值)
返回
Integer.MIN_值
。可以修改为
Math.abs(hashVal%20011)
,尽管我不确定它如何影响分布。@StefanWarminski更新以反映这种特殊情况。@JaroslawPawlak否,
Math.abs(hashVal%20011)=(hashVal%20011)
即使hashVal为负。但是,您可以执行
((hashVal%20011)+20011)%20011)
了解更多信息。请注意
Math.abs(Integer.MIN_值)
返回
Integer.MIN_值
。可以修改为
Math.abs(hashVal%20011)
虽然我不确定它是如何影响分发的。@StefanWarminski更新以反映这种特殊情况。@JaroslawPawlak否,
Math.abs(hashVal%20011)=(hashVal%20011)
即使hashVal为负值。但是,您可以执行
((hashVal%20011)+20011)%20011)
以了解详细信息。