Java remove()功能不正常

Java remove()功能不正常,java,arrays,hash,hashtable,double-hashing,Java,Arrays,Hash,Hashtable,Double Hashing,在下面的Main方法中,为什么不删除最后一个单词(clapping) 输出是 [Media, digitize, airplane, canonicalized, spoilers, distilling, clapping, knit, libraries, speaks, residues] [Media, digitize, airplane, null, spoilers, null, clapping, null, null, speaks, residues] 拍手不会被删除。为什

在下面的
Main
方法中,为什么不删除最后一个单词(
clapping

输出是

[Media, digitize, airplane, canonicalized, spoilers, distilling, clapping, knit, libraries, speaks, residues]
[Media, digitize, airplane, null, spoilers, null, clapping, null, null, speaks, residues]
拍手
不会被删除。为什么?

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);
    }
}
公共类HT{
公共字符串[]集;
公共整数大小;
公共卫生署(){
this.set=新字符串[11];
此值为0.size=0;
}
公共空白插入(字符串字){
int hash1=给定hash1(单词);
int hash2=giveHash2(单词);
while(设置[hash1]!=null){
hash1+=hash2;
hash1%=set.length;
}
set[hash1]=word;
大小++;
}
公共无效删除(字符串字){
int hash1=给定hash1(单词);
int hash2=giveHash2(单词);
while(set[hash1]!=null&&!set[hash1].equals(word)){
hash1+=hash2;
hash1%=set.length;
}
set[hash1]=null;
大小--;
}
公共整数给定哈希代码(字符串s){
int hash=0,x=31;

对于(int i=0;i而言,问题很可能是
remove()
方法中循环的终止条件

while (set[hash1] != null && !set[hash1].equals(word)) {
它在找到的第一个
null
值处终止

插入时,如果位置已被占用,则更新的是
hash1
,因此单词的最终位置取决于现有插入的单词,即已占用的位置


但是,当您已经删除了一些值时,
remove()
中的循环可能会找到空位置(
null
值)更快,并在实际到达
单词最初插入的位置之前终止。

只是好奇,但这种奇怪的双哈希算法是从哪里来的?您可能希望使用调试器逐步检查代码并查看值。因为您在尝试删除我的gue时更改了
哈希1
ss是结果哈希与用于插入的哈希不同,因此错误的bucket被设置为null。我支持Shadab,因为这是一个非常奇怪的哈希算法。另外注意:由于您的
insert()
似乎试图通过更改哈希来避免冲突,直到您找到一个可能运行一段时间的空白点,尤其是在搜索最后一个可用的bucket时。这也会根据插入顺序产生不同的哈希,这不仅会导致删除问题,而且会导致任何其他需要删除的操作出现大量问题o查找给定的单词-你不能只通过哈希或搜索单个bucket来访问单词,但可能必须搜索整个哈希表。你的remove函数会删除第一个非空条目,即使它不匹配。我明白了,那么有哪些好的哈希函数呢?这些函数是我在大学和互联网上学习的混合函数。顺便说一句
giveHash2()
实际上应该使用7,但我将其更改为3,因为它导致的冲突较少。如果提到一些好的哈希函数,那就太好了。我尝试不使用内置的哈希类,而是自己实现它。哦,我明白了,那么可能的解决方法是什么?在
条件导致出现
NullPointerException
。在执行打开寻址时,通常最好区分“此位置始终为空”和“此位置的值已删除”。如果可以将位置标记为“此位置的值已删除”然后,你可以在插入和搜索时将其视为空,但在调用
remove
thx时对其进行迭代!我刚刚实现了它,现在它可以工作了。顺便说一句,既然你说我的哈希函数很奇怪,你能修改你的答案以包含一些可能导致较少冲突的好函数吗
while (set[hash1] != null && !set[hash1].equals(word)) {