【发布时间】:2021-05-21 03:05:21
【问题描述】:
在下面的Main 方法中,为什么最后一个字(clapping)没有被删除?
public class Main {
public static void main(String[] args) {
HT ht = new HT();
ht.insert("airplane");
ht.insert("distilling");
ht.insert("speaks");
ht.insert("knit");
ht.insert("digitize");
ht.insert("Media");
ht.insert("canonicalized");
ht.insert("libraries");
ht.insert("clapping");
ht.insert("residues");
ht.insert("spoilers");
System.out.println(Arrays.toString(ht.set));
ht.remove("distilling");
ht.remove("knit");
ht.remove("canonicalized");
ht.remove("libraries");
ht.remove("clapping");
System.out.println(Arrays.toString(ht.set));
}
}
输出是
[Media, digitize, airplane, canonicalized, spoilers, distilling, clapping, knit, libraries, speaks, residues]
[Media, digitize, airplane, null, spoilers, null, clapping, null, null, speaks, residues]
clapping 不会被删除。为什么?
HT.java
public class HT {
public String[] set;
public int size;
public HT() {
this.set = new String[11];
this.size = 0;
}
public void insert(String word) {
int hash1 = giveHash1( word );
int hash2 = giveHash2( word );
while (set[hash1] != null) {
hash1 += hash2;
hash1 %= set.length;
}
set[hash1] = word;
size++;
}
public void remove(String word) {
int hash1 = giveHash1(word);
int hash2 = giveHash2(word);
while (set[hash1] != null && !set[hash1].equals(word)) {
hash1 += hash2;
hash1 %= set.length;
}
set[hash1] = null;
size--;
}
public int giveHashCode(String s) {
int hash = 0, x = 31;
for(int i=0;i<s.length();i++) {
hash = x * hash + s.charAt(i);
}
return hash;
}
private int giveHash1(String s) {
return (giveHashCode(s) % set.length < 0)
? (giveHashCode(s) % set.length) + set.length
: giveHashCode(s) % set.length;
}
private int giveHash2(String s) {
return 3 - (((giveHashCode(s) % set.length < 0)
? (giveHashCode(s) % set.length) + set.length
: giveHashCode(s) % set.length) % 3);
}
}
除了修饰符之外,代码有什么问题吗?可能使用哈希函数,或者可能使用insert() 或remove()?
【问题讨论】:
-
只是好奇,但是你从哪里得到这个奇怪的双重哈希算法?
-
您可能希望使用调试器单步执行代码并查看值。由于您在尝试消除我的猜测时更改了
hash1,因此生成的哈希与用于插入的哈希不同,因此错误的存储桶设置为空。我对 Shadab 表示赞同,因为这是一个非常奇怪的哈希算法。 -
附加说明:因为您的
insert()似乎试图通过更改哈希来避免冲突,直到您找到一个可能会运行一段时间的空点,尤其是在搜索最后一个可用存储桶时。这也会根据插入顺序导致不同的哈希,这不仅会导致很多问题,而且不仅会导致删除,还会导致任何其他需要查找给定单词的操作 - 您不能只通过哈希或搜索来访问单词单个存储桶,但可能必须搜索整个哈希表。 -
您的删除函数会删除第一个非空条目,即使它不匹配。
-
我明白了,那么有哪些好的散列函数呢?这些 r 是我在大学和互联网上所学的混合体。顺便说一句,
giveHash2()在现实中应该使用 7,但我将其更改为 3,因为它造成的碰撞更少。如果能提到一些好的散列函数就好了。我试图不使用内置的哈希类,而是自己实现它。
标签: java arrays hash hashtable double-hashing