Member 13803558 Ответов: 1

У меня есть исключение в потоке "main" java.lang.arrayindexoutofboundsexception: -47 ошибка в моей домашней работе


мой код таков:

package code;

import java.lang.reflect.Array;
import java.util.LinkedList;

import given.AbstractHashMap;
import given.HashEntry;
import given.iPrintable;

/*
 * The file should contain the implementation of a hashmap with:
 * - Open addressing for collision handling
 * - Double hashing for probing. The double hash function should be of the form: q - (k mod q)
 * - Multiply-Add-Divide (MAD) for compression: (a*k+b) mod p
 * - Resizing (to double its size) and rehashing when the load factor gets above a threshold
 * 
 * Some helper functions are provided to you. We suggest that you go over them.
 * 
 * You are not allowed to use any existing java data structures other than for the keyset method
 */

public class HashMapDH<Key, Value> extends AbstractHashMap<Key, Value> {

	// The underlying array to hold hash entries (see the HashEntry class)
	private HashEntry<Key, Value>[] buckets;

	@SuppressWarnings("unchecked")
	protected void resizeBuckets(int newSize) {
		// Update the capacity
		N = nextPrime(newSize);
		buckets = (HashEntry<Key, Value>[]) Array.newInstance(HashEntry.class, N);
	}

	// The threshold of the load factor for resizing
	protected float criticalLoadFactor;

	// The prime number for the secondary hash
	int dhP;

	/*
	 * ADD MORE FIELDS IF NEEDED
	 * 
	 */

	/*
	 * ADD A NESTED CLASS IF NEEDED
	 * 
	 */

	// Default constructor
	public HashMapDH() {
		this(101);
	}

	public HashMapDH(int initSize) {
		this(initSize, 0.6f);
	}

	public HashMapDH(int initSize, float criticalAlpha) {
		N = initSize;
		criticalLoadFactor = criticalAlpha;
		resizeBuckets(N);

		// Set up the MAD compression and secondary hash parameters
		updateHashParams();

		/*
		 * ADD MORE CODE IF NEEDED
		 * 
		 */
	}

	/*
	 * ADD MORE METHODS IF NEEDED
	 * 
	 */

	/**
	 * Calculates the hash value by compressing the given hashcode. Note that you
	 * need to use the Multiple-Add-Divide method. The class variables "a" is the
	 * scale, "b" is the shift, "mainP" is the prime which are calculated for you.
	 * Do not include the size of the array here
	 * 
	 * Make sure to include the absolute value since there maybe integer overflow!
	 */
	protected int primaryHash(int hashCode) {
		// TODO: Implement MAD compression given the hash code, should be 1 line
		return (hashCode*a+b)%P % N;
	}

	/**
	 * The secondary hash function. Remember you need to use "dhP" here!
	 * 
	 */
	protected int secondaryHash(int hashCode) {
		// TODO: Implement the secondary hash function taught in the class
		return dhP-hashCode%dhP;
	}

	@Override
	public int hashValue(Key key, int iter) {
		int k = Math.abs(key.hashCode());
		return Math.abs(primaryHash(k) + iter * secondaryHash(k)) % N;
	}

	/**
	 * checkAndResize checks whether the current load factor is greater than the
	 * specified critical load factor. If it is, the table size should be increased
	 * to 2*N and recreate the hash table for the keys (rehashing). Do not forget to
	 * re-calculate the hash parameters and do not forget to re-populate the new
	 * array!
	 */
	protected void checkAndResize() {
		if (loadFactor() > criticalLoadFactor) {
			// TODO: Fill this yourself
			int oldn=n;
			updateHashParams();
			HashEntry<Key, Value>[] temp=buckets;
			resizeBuckets(2*N);
			for(int i=0;i<temp.length;i++) {
				buckets[i]=temp[i];
			}
			n=oldn;

		}
	}


	@Override
	public Value get(Key k) {
		// TODO Auto-generated method stub
		
		int hash1 = primaryHash(k.hashCode() );
        int hash2 = secondaryHash(k.hashCode() );
 
        while (buckets[hash1] != null && !buckets[hash1].getKey().equals(k))
        {
            hash1 += hash2;
            hash1 %= N;
        }
        return buckets[hash1].getValue();
	}

	@Override
	public Value put(Key k, Value v) {
		// TODO Auto-generated method stub
		// Do not forget to resize if needed!
		if(n==N) {
			checkAndResize();
		}

		int hash1=primaryHash(k.hashCode());
		int hash2=secondaryHash(k.hashCode());

		while(buckets[hash1]!=null) {
			hash1+=hash2;
			hash1%=N;
		}
		buckets[hash1]=new HashEntry<Key,Value>(k,v);
		n++;

		return buckets[hash1].getValue();
	}

	@Override
	public Value remove(Key k) {
		// TODO Auto-generated method stub

		int hash1=primaryHash(k.hashCode());
		int hash2=secondaryHash(k.hashCode());

		while(buckets[hash1]!=null && !buckets[hash1].getKey().equals(k)) {

			hash1 += hash2;
			hash1 %= N;

		}
		HashEntry<Key, Value> temp=new HashEntry<Key,Value>(buckets[hash1].getKey(),buckets[hash1].getValue());

		buckets[hash1]=null;
		n--;


		return temp.getValue();
	}

	// This is the only function you are allowed to use an existing Java data
	// structure!
	@Override
	public Iterable<key> keySet() {
		// TODO Auto-generated method stub
		LinkedList<key> r=new LinkedList<key>();
		for(int i=0;i<buckets.length;i++) {
			HashEntry<Key,Value> e;
			e=buckets[i];
			if(e!=null) {
				r.add(e.getKey());
			}
		}
		return r;
	}

	@Override
	protected void updateHashParams() {
		super.updateHashParams();
		dhP = nextPrime(N / 2);
	}

}


У меня тоже есть эти ошибки:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -47
	at code.HashMapDH.get(HashMapDH.java:136)
	at given.TestHashMap.testGet(TestHashMap.java:119)
	at given.TestHashMap.testAll(TestHashMap.java:246)
	at given.Test.main(Test.java:464)

ошибка в коде.HashMapDh.get(HashMapDH.java:136) строка 136-это цикл while методов get. Я не знаю как это исправить пожалуйста помогите мне

Что я уже пробовал:

Это часть моей домашней работы. Я не мог исправить ошибки, не могли бы вы мне помочь? это дает ошибки
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -47
	at code.HashMapDH.get(HashMapDH.java:136)
	at given.TestHashMap.testGet(TestHashMap.java:119)
	at given.TestHashMap.testAll(TestHashMap.java:246)
	at given.Test.main(Test.java:464)

1 Ответов

Рейтинг:
0

OriginalGriff

Внимательно посмотрите на сообщение об ошибке: оно дает вам много информации!

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -47
Это означает, что вы попытались получить доступ к элементу массива, который не существует. Например, вы попытались использовать отрицательный индекс массива или из массива, содержащего четыре элемента, вы попытались использовать индекс, который равен 4 или больше (массивы в Хавеа основаны на 0, поэтому допустимыми индексами будут только 0, 1, 2 и 3).

Следующий бит сообщения об ошибке сообщает вам, где это произошло:
at code.HashMapDH.get(HashMapDH.java:136)
Этот файл ... HashMapDH.java", номер строки - "136", а ошибка - в функции "get"

Поэтому начните с определения того, какая строка является "номером строки 136" (попробуйте CTRL+G в вашей IDE, что часто приводит вас непосредственно к номеру строки), а затем используйте отладчик, чтобы узнать, каковы фактические индексы массива и насколько велик ваш массив.

Извините, но мы не можем сделать это для вас - мы не можем запустить ваш код с теми же данными - время для вас, чтобы изучить новый (и очень, очень полезный) навык: отладка!