Как найти среднюю длину корзины в хэш-карте?

#java #hashmap

#java #hashmap

Вопрос:

Я выполняю назначение класса, и он просит нас создать хэш-карту, а затем заполнить ее случайными значениями, сначала без динамического изменения размера, а затем с динамическим изменением размера, чтобы увидеть разницу в скорости, которую меньшие размеры корзины создают при хранении значений.

Для этого он просит меня создать метод, который находит самую короткую длину корзины, среднюю длину корзины и самую длинную длину корзины в хэш-карте.

Здесь я сталкиваюсь с проблемами, поскольку, когда я пытаюсь получить длины сегментов, он всегда возвращает ноль. Я не уверен, в чем заключается моя проблема, поскольку мой код логически имеет смысл для меня. Любая помощь будет с благодарностью принята.

Ниже приведен код для моей хэш-карты и моей основной программы, которая ее вызывает.

 public class MyHashMap<K, V> {
    private LinkedList<KVP <K, V>>[] bucket;
    private int M = 5;
    private int size = 0;


    public MyHashMap(int M){
        this.bucket = (LinkedList<KVP<K, V>>[]) new LinkedList[M];
        for(int i = 0; i < M; i  ){
            bucket[i] = new LinkedList<KVP<K, V>>();
        }
    }
    public MyHashMap(){
        this.bucket = (LinkedList<KVP<K, V>>[]) new LinkedList[M];
        for(int i = 0; i < 5; i  ){
            bucket[i] = new LinkedList<KVP<K, V>>();
        }
    }

    public int getBucketNumber(K key){
        return Math.abs(key.hashCode()) % this.bucket.length;
    }
    public void put(K key, V value){
        //resize();
        size  ;
        int b = getBucketNumber(key);
        for(KVP<K, V> pair : this.bucket[b]){
            if(pair.key.equals(key)){
                pair.value = value;
                return;
            }
        }
        KVP<K, V> pair = new KVP<>(key, value);
        this.bucket[b].add(pair);
    }
    public int size(){
        return this.bucket.length;
    }
    public boolean isEmpty(){
        return size == 0;
    }
    public void resize(){
      if(size > size() * 2){
          LinkedList<KVP <K, V>>[] newHash = (LinkedList<KVP<K, V>>[]) new LinkedList[2 * size()];
          for(int i = 0; i < newHash.length; i  ){
              newHash[i] = new LinkedList<KVP <K, V>>();
          }
          for(LinkedList<KVP<K, V>> map: this.bucket){
              for(KVP<K, V> pair: map){
                  int newHashCode = Math.abs(pair.key.hashCode()) % newHash.length;
                  newHash[newHashCode].add(pair);
              }
          }
          this.bucket = newHash;
      }     
    }

    public void delete(K key){
        int b = getBucketNumber(key);
        for(KVP<K, V> pair : this.bucket[b]){
            if(pair.key.equals(key)){
                key = null;
            }
        }
    }
    public boolean containsKey(K key){
        int b = getBucketNumber(key);
        boolean t = false;
        for(KVP<K, V> pair : this.bucket[b]){
            if(pair.key.equals(key)){
                t = true;
            }else{
                t = false;
            }
        }
            return t;
    }
    public V get(K key){
        int b = getBucketNumber(key);
        for(KVP<K, V> pair : this.bucket[b]){
            if(pair.key.equals(key)){
                return pair.value;
            }
        }
        return null;
    }
    public int Avg(){
        int j = 0;
        for(int i = 0; i < bucket.length; i  ){
            j  = bucket[i].size();
        }
        return j/bucket.length;
    }

}

public class hwMain {
    public static void main(String[] args){

        int N = (int) Math.pow(10, 3);
        MyHashMap<Integer, Integer> store = new MyHashMap<>();      
        for(int i = 0; i < N; i  ){

            store.put((int) Math.random(), 1);
            }
        System.out.print(store.Avg());
    }
}
  

Комментарии:

1. Подсказка: int / int -> int, поэтому 1/2 = 0.

2. Одно улучшение, не связанное с вопросом: вы также можете изменить размер корзины при удалении, поскольку это уменьшит пространство и освободит лишние пробелы

Ответ №1:

Потому что, согласно Math.random() :

Возвращает двойное значение с положительным знаком, большее или равное 0.0 и меньшее 1.0.

Поскольку число всегда меньше 1.0, когда вы делаете это:

 (int) Math.random()
  

Это всегда возвращает 0 (ноль).

Решение:

Если у вас есть диапазон случайных чисел и минимальное значение, используйте это:

 (int) (Math.random() * range)   minimum
  

Например: вы хотите взять случайные числа от 1 до 100.

 (int) (Math.random() * 100)   1
  

Комментарии:

1. Фактические значения не повлияют на среднее количество пар ключ-значение на сегмент, даже если они меньше 1, поскольку ключи используются только для вычисления хэш-кода перед сортировкой по сегментам. Ну, я имею в виду, что они делают, но поскольку они случайны, это не должно заметно влиять на среднее значение для каждого сегмента.

2. Для всех put значение key будет равно 0. Не будет ли это проблемой??

3. Я понимаю, что вы имеете в виду сейчас, но когда я добавляю минимум и диапазон, теперь он каждый раз возвращает значение 20, поэтому я не уверен, что это была проблема.

4. Каковы значения диапазона и минимума?

5. Я установил диапазон в 100, а минимальный — в 1, как у вас. Кроме того, я использовал другое предложение и изменил вычисления среднего метода для получения двойных чисел вместо целых. Я не уверен, что эти две вещи отрицательно влияют друг на друга.