2017-04-04 92 views
2

我遇到了我的HashTable问题。虽然代码编译并运行得很好,但我没有得到我期望的输出。HashTable不输出正确的数据

final HashTable应该有一个表大小10;苏(453)和鲍比(170)应该在索引1,罗伯特(348)在索引2,马克(231)在3和乔治(15)在6。而当我运行我的程序,我的HashTable看起来完全不同它的大小为22,Bobby有两个值(应该删除一个),所以我不确定我做错了什么。

我有一个怀疑,我搞砸了"put"方法,但我不能包装我的头围绕可能存在的问题,以及为什么比较失败时,试图删除第一个Bobby值,而不是添加它在旧的价值之上。

public class HashTable <K, V> 
{ 
    private HashItem[] table; 
    private int count; 
    private double loadFactor; 

    private static final int DEFAULT_CAPACITY = 5; 
    private static final double DEFAULT_LOAD_FACTOR = 0.75; 

private class HashItem <K, V> 
{ 
    private int hash; 
    private K key; 
    private V value; 
    private HashItem <K, V> next; 

    public HashItem(int hashIn, K keyIn, V valueIn, HashItem<K, V> nextIn) 
    { 
    hash = hashIn; 
    key = keyIn; 
    value = valueIn; 
    next = nextIn; 
    } 
} 

public HashTable(int initialCapacity, double loadFactorIn) 
{ 
    if(initialCapacity <= 0) 
    { 
    throw new 
      IllegalArgumentException("Capacity must be > 0."); 
    } 
    if(loadFactorIn < 0) 
    { 
    throw new IllegalArgumentException("Load factor must be > 0."); 
    } 
    loadFactor = loadFactorIn; 
    table = new HashItem[initialCapacity]; 
} 

public HashTable() 
{ 
    this(DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR); 
} 

public int size() 
{ 
    return count; 
} 

private void rehash() 
{ 
    HashItem[] oldTable = table; 

    //create new table 
    int capacity = oldTable.length * 2 + 1; 
    table = new HashItem[capacity]; 

    //get elements at each old table index 
    for(int i = 0; i< oldTable.length; i++) 
    { 
     HashItem<K, V> item = oldTable[i]; 
     //add the element from old table and its linked elements 
     while(item != null) 
     { 
     put(item.key, item.value); 
     item = item.next; 
     } 
    } 
} 

public V put(K keyIn, V valueIn) 
{ 
    if (valueIn == null) 
    { 
    throw new IllegalArgumentException("Value cannot be null"); 
    } 

    int hash = Math.abs(keyIn.hashCode()); 
    int index = hash % table.length; 

    // get hash item at target location(if any) 
    HashItem<K , V> current = table[index]; 
    // iterate through linked nodes at the location (if any) 
    while(current != null) 
    { 
     //if an item with the same hash & key is there, replace 
     if(hash == current.hash && current.key.equals(current.hash)) 
     { 
     V oldItem = current.value; 
     current.value = valueIn; 
     return oldItem; 
     } 
    current = current.next; 
    }  

    int threshold = (int) (table.length * loadFactor); 
    if(size() >= threshold) 
    { 
     rehash(); 
     index = hash % table.length; 
    } 

    current = table[index]; 
    table[index] = new HashItem <K, V>(hash, keyIn, valueIn, current); 
    count++; 

    return valueIn; 
} 

public V get(Object keyIn) 
{ 
    int hash = Math.abs(keyIn.hashCode()); 
    int index = hash % table.length; 

    HashItem<K, V> item = table[index]; 
    while(item != null) 
    { 
     if(hash == item.hash && item.key.equals(keyIn)) 
     { 
     return item.value; 
     } 
     item = item.next; 
    } 
return null; 
} 

public boolean remove(Object keyIn) 
{ 
    int hash = Math.abs(keyIn.hashCode()); 
    int index = hash % table.length; 

    HashItem<K, V> item = table[index]; 
    HashItem<K, V> previous = null; 
    while(item != null) 
    { 
     if(item.key.equals(keyIn)) 
     { 
     //if it is not in root node, replace links 
     if(previous != null) 
     { 
      previous.next = item.next; 
     } 
     //if it was the root, move next item in the chain down 
     else{ 
      table[index] = item.next; 
      } 
     count--; 
     return true; 
    }   
    previous = item; 
    item = item.next; 
    } 
    return false; 
} 

public void makeEmpty() 
    { 
     table = new HashItem[table.length]; 
     count = 0; 
    } 

public static void main(String [] args) 
{ 
    HashTable<String, Integer> purchases = new HashTable <String, Integer>(); 

    String names[] = {"Yuan", "Bobby", "Kevin"}; 

    purchases.put(names[0], 654); 
    purchases.put(names[1], 341); 
    purchases.put(names[2], 70); 

    purchases.put(names[1], 170); 

    System.out.println("Yuan: " + purchases.get(names[0])); 
    System.out.println("Bobby: " + purchases.get(names[1])); 
    System.out.println("Kevin: " + purchases.get(names[2])); 

    purchases.remove(names[0]); 
    purchases.remove(names[2]); 

    purchases.put("Robert" , 348); 
    purchases.put("Sue", 453); 
    purchases.put("Mark", 231); 
    purchases.put("George", 15); 
}  
} 
+1

欢迎来到Stack Overflow!它看起来像你需要学习使用调试器。请帮助一些[互补调试技术](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/)。如果您之后仍然遇到问题,请随时返回一个[最小,完整且可验证的示例](http://stackoverflow.com/help/mcve),以说明您的问题。 –

回答

1

通过您的代码浏览。这个问题似乎与你Rehash方法。当你在rehash()中再次调用put时,put方法不知道调用是作为插入还是rehash从用户来的。即使调用不正确的重新刷新,count变量也会增加。

Kindle使用调试器来帮助您解决其他问题。一个快速的谷歌搜索调试程序将有所帮助。

编辑:里面把方法current.key.equals(current.hash)不应该这个比较更像 current.key.equals(keyIn)..原来可能永远不会是真的,这就是为什么更换不起作用。

希望这会有所帮助

+0

非常感谢,将'current.hash'改为'keyIn'似乎已经成功了。我似乎已经感到困惑,因为我认为我们将密钥与哈希进行比较,看看它们是否相等,所以我认为'current.hash'是唯一能够工作的东西。 – Abe