2017-04-04 186 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