2017-03-10 13 views
1

私は私のハッシュマップstudentMapのキーをハッシュしている私のリニアメソッドで衝突を検出しようとしています。私は線形プロービングのための基本的な機能を持っていますが、キーがすでに存在するかどうかを検出するために苦労しています(したがって+ 1)。これまでのところ、このコードは機能しません。地図のStudentMapからそのキーが存在するかどうかをチェックしません。 ご迷惑をおかけして申し訳ありません。他のハッシュメソッドのいくつかを削除して、このコードのサイズを無関係にするようにしました。衝突の分解線形プロービングJava

public class Main { 
    Student student; 
    public static boolean vartrue; 
    HashMap next; 
    public HashMap<String,Student> studentMap; 
    public static void main(String[] args) throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException, NoSuchFieldException { 
     HashMap<String, String> studentMap = new HashMap<>(16, 0.75f); 
     //et keys and value 
     studentMap.keySet().forEach((key) -> { 
      String value = studentMap.get(key); 
      System.out.println("Key = " + key + ", Value = " + value); 
     }); 
     //adding values to array 
     studentMap.put("16012804", "Jennifer"); 
     studentMap.put("13747732", "Beatrice"); 
     studentMap.put("14056983", "Mavis"); 
     studentMap.put("16013464", "Geoffrey"); 
     studentMap.put("14058392", "Bob"); 
     studentMap.put("15405833", "Bill"); 
     studentMap.put("14058039", "Gertrude"); 
     studentMap.put("13056496", "Dorothy"); 
     //iterating through the array 
     Set set = studentMap.entrySet(); 
     Iterator iterator = set.iterator(); 
     while(iterator.hasNext()) { 
      Map.Entry mapentry = (Map.Entry)iterator.next(); 
      System.out.print("Key is: "+ mapentry.getKey() + " & Value is: "); 
      System.out.println(mapentry.getValue()); 
     } 
     //Get values based on key 
     String var= studentMap.get("16012804"); 
     System.out.println("Value at index 1 is: "+var); 
     // Remove values based on key 
     studentMap.remove("16012804"); 
     System.out.println("Map key and values after removal:"); 
     Set set2 = studentMap.entrySet(); 
     Iterator iterator2 = set2.iterator(); 
     while(iterator2.hasNext()) { 
      Map.Entry mapentry2 = (Map.Entry)iterator2.next(); 
      System.out.print("Key is: "+mapentry2.getKey() + " & Value is: "); 
      System.out.println(mapentry2.getValue()); 
     } 
     Set keyset = studentMap.keySet(); 
     System.out.println("Key set values are:" + keyset); 
     boolean val = studentMap.isEmpty(); 
     System.out.println("Is hash map empty: " + val); 
     //get values 
     Collection<String> values = studentMap.values(); 
     System.out.println("Map values = " + values); 
     //size of table 
     System.out.println("Size of the Hashtable: " + studentMap.size()); 
     //initial capacity 
     System.out.println("Initial Capacity: " + 16); 
     //capacity of map 
     System.out.println("Map capacity: " + mapcapacity(studentMap)); 
     //load factor 
     System.out.println("Load Factor: " + loadFactor(studentMap)); 

     //linear probing 
     System.out.println("..."); 
     System.out.println("Hash Value(\"Jennifer\")="+ linear(studentMap, "16012804")); 
     System.out.println("Hash Value(\"Mavis\")="+ linear(studentMap, "14056983")); 
     System.out.println("Hash Value(\"Geoffrey\")="+ linear(studentMap, "16013464")); 
     System.out.println("Hash Value(\"Bill\")="+ linear(studentMap, "15405833")); 
     System.out.println("Hash Value(\"Gertrude\")="+ linear(studentMap, "14058039")); 
     System.out.println("Hash Value(\"Beatrice\")="+ linear(studentMap, "13747732")); 
     System.out.println("Hash Value(\"Bob\")="+ linear(studentMap, "14058392")); 

     if (vartrue = true) 
      { 
      Map<String, String> map1 = new HashMap<>(mapcapacity(studentMap) * 2); 
      map1.putAll(studentMap); 
      //capacity of the new hash map. (reflection) 
      System.out.println("Map 1 mappings= " + map1); 
      Field tableField = HashMap.class.getDeclaredField("table"); 
      tableField.setAccessible(true); 
      Object[] table = (Object[]) tableField.get(map1); 
      System.out.println("Size of Map 1: "); 
      System.out.println(table == null ? 0 : table.length); 
      } 

     } 
    //when to increase the hashmap size is calculated by capacity of hashmap divided by load factor: 
    public static double loadFactor(Map studentMap){ 
    double count = studentMap.size(); 
     double load = count/mapcapacity(studentMap); 
     return load; 
    } 
    //if the size of the map is greater than the map capacity * load factor - then double the size of map. 
    public static Integer mapcapacity(Map studentMap){ 
     //default capacity and load factor 
     Integer initCapacity= 11; 
     float loadFactor=0.75f; 
     boolean capacityFound=false; 
     Integer capacity=initCapacity; 
     Integer size=studentMap.size(); 
     while(!capacityFound){ 
      if(size>capacity*loadFactor){ 
       //increase capacity 
       capacity=capacity * 2; 
       vartrue = true; 
      } 
      else { 
       capacityFound=true; 
      } 
     } 
     return capacity; 
    } 




    //linear probing 
    public static int hashThis(String key, Map studentMap) { 
     return key.hashCode()& 0x7fffffff % mapcapacity(studentMap); 
    } 
    public static int linear(Map studentMap, String key){ 
    String value = studentMap.get(key).toString(); 
    int counter = 0; 
    int hash = hashThis(key, studentMap); 
    if (value != null) 
    { 
    hash = (hash + 1) % mapcapacity(studentMap); 
    counter ++; 
    } 
    else{ 
     return 0; 
    } 
    return hash; 
    } 


} 

答えて

0

は、私の知る限り理解し、あなたではなく、すでに線形探査方法で実行されているjava.util.HashMapを使用するよりも、手動で独自のハッシュマップを実装することに決めました。 その場合、java.util.HashMapのソースは大きなヒントになる可能性があります。 "grepcode.com"サイトから、私はjava.util.HashMapput(K key, V value)メソッドのソースコードを次のように見つけました。 addEntry()

public V put(K key, V value) { 
    ... // null check on key : omitted 

    int hash = hash(key.hashCode()); 
    int i = indexFor(hash, table.length); 

    for (Entry<K,V> e = table[i]; e != null; e = e.next) { 
     Object k; 
     if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { 
      ... // if the same key already exists, return the old value : omitted 
     } 
    } 
    modCount++; 
    addEntry(hash, key, value, i); 
    return null; 
} 

と呼ばれ、for文は利用可能なスペースを探して繰り返されます。つまり、forループを終了するときには、iは、新しいエントリの使用可能な領域のインデックスを示します。また、put()のデュアルメソッドであるget()を確認して理解を深めることができます。

ここで最も重要なことは、java.util.HashMapは、リニアプロービングの「ハッシュコードを変更する」ようではないと思います。あなたのコードのlinear()は、keyのためにhashを調整するように見えるので、これはあなたのアプローチとの主な違いです。ハッシュ値のためのスペースがすでに取られているときはいつも。

さらに、コード内のlinear()は、空き領域を検索するための反復を使用しませんが、サイズ拡張の場合はmapcapacity()です。これは、単一のキー挿入のために複数のスペース調整を引き起こす可能性があるため、線形のプロービングの効率的な方法のようには見えません。

要約すると、java.util.HashMapまたは関連するクラスのソースコードを確認することをお勧めします。)