Java 这个散列函数的效率如何?

Java 这个散列函数的效率如何?,java,algorithm,hash,Java,Algorithm,Hash,我不确定将“词典”散列到表中的最佳方法 字典有61406个单词,我通过SizeOFDictionary/.75确定重载 这给了我81874桶的桌子 我通过我的散列函数(通用随机算法)运行它,有31690个桶被用完了。还有五万多个是空的。最大的桶只包含10个单词 我的问题是:这些数字是否足以用于哈希项目?我不熟悉我想要实现的目标,对我来说,五万多只不过是一堆空桶 这是我的哈希函数 private void hashingAlgorithm(String word) { int key =

我不确定将“词典”散列到表中的最佳方法

字典有61406个单词,我通过SizeOFDictionary/.75确定重载

这给了我81874桶的桌子

我通过我的散列函数(通用随机算法)运行它,有31690个桶被用完了。还有五万多个是空的。最大的桶只包含10个单词

我的问题是:这些数字是否足以用于哈希项目?我不熟悉我想要实现的目标,对我来说,五万多只不过是一堆空桶

这是我的哈希函数

private void hashingAlgorithm(String word)
{
    int key = 1;
    //Multiplying ASCII values of string
    //To determine the index
    for(int i = 0 ; i < word.length(); i++){
        key *= (int)word.charAt(i);
        //Accounting for integer overflow
        if(key<0)
            key*=-1;
    }
    key %= sizeOfTable;
    //Inserting into the table
    table[key].addToBucket(word);       
}
private void散列算法(字符串字)
{
int键=1;
//将字符串的ASCII值相乘
//确定指数
for(int i=0;i如果(关键字if)词典包含以下单词:

abdc  
abcd  
dbca  
dabc  
dacb   
在哈希表中,所有值都将被哈希到相同的值,即
int(a)*int(b)*int(c)*int(d)
,这不是一个好主意。
所以,使用滚动散列

示例
hash=[0]*base^(n-1)+[1]*base^(n-2)+……+[n-1]

其中基数是一个质数,比如说31

注意
[i]
表示
char.at(i)

您还可以使用
模p
[显然p是质数]运算符来避免
溢出
,并限制哈希表的
大小


hash=[0]*base^(n-1)+[1]*base^(n-2)+……+[n-1]mod p

性能分析:

你的哈希函数不考虑顺序。根据你的算法,如果没有溢出,
ab=ba
。你的代码依赖于溢出来区分不同的顺序。因此,如果你认为句子是一个基于N的数字,那么会有很多额外的冲突空间,可以消除这些冲突

改进建议:

2*3==3*2
但是
2*223+3!=3*223+2


因此,如果我们将字符串表示为基于N的数字,那么冲突的数量将显著减少。

String.hashCode()有什么问题
?我应该创建自己的散列算法。这是一个类项目。好的,这是一个散列算法。但我觉得它不太好。至少将字符值乘以您选择的整数,而不是与键相乘,将它们添加到键中,并在每一步进行模运算。@fall,我会这样做,您能告诉我是什么吗选择我选择的整数的目的是什么?2*3==3*2但是(2*10+3)!=(3*10+2)…key*=(int)word.charAt(i)*BASE^(word.length()-(i-1));我试过了,现在抛出了一个异常,声明数组超出了范围-10502你需要这样做:
(a+b+c)%mod=a%mod+b%mod+c%mod
而且,由于
a*b
可能超出整数范围。
(a*b)%mod=(a%mod*b%mod)%mod
。我以为你对它很熟悉,所以没有把它包括在回答中。同样对于
a*b
使用
long
。单词的最大长度是多少?没有单词的最大长度,这是一个猜测,因为你需要计算31^最大长度