Java 哈希表中的冲突解析
我正试图用Java构建自己的哈希表实现,以便更好地掌握哈希的工作原理。当负载超过75%或我有一条超过20长的单链时,我会使用单独的链,增加表的大小,并重新灰化所有内容。我正在散列字符串。我已经尝试了所有我能想到的方法,但是当我尝试构建表时,它会运行几秒钟,然后在我的grow方法中抛出StackOverflower错误 这是实际哈希表的代码,包括实际表的arrayList和一些用于跟踪最长链、冲突数和大小的int。它还包括插入、增长(在新arrayList中重新刷新所有内容)、散列字符串以及查找高于给定数字的素数以及getter/setter的方法Java 哈希表中的冲突解析,java,arraylist,hash,stack-overflow,Java,Arraylist,Hash,Stack Overflow,我正试图用Java构建自己的哈希表实现,以便更好地掌握哈希的工作原理。当负载超过75%或我有一条超过20长的单链时,我会使用单独的链,增加表的大小,并重新灰化所有内容。我正在散列字符串。我已经尝试了所有我能想到的方法,但是当我尝试构建表时,它会运行几秒钟,然后在我的grow方法中抛出StackOverflower错误 这是实际哈希表的代码,包括实际表的arrayList和一些用于跟踪最长链、冲突数和大小的int。它还包括插入、增长(在新arrayList中重新刷新所有内容)、散列字符串以及查找高
import java.util.ArrayList;
import java.util.LinkedList;
public class HashTable {
private ArrayList<LinkedList<String>> hashes;
private int collisionCounter; //the total amount of collisions that have occurred
private int longest; //the length collision
private int size;
public HashTable(int size) {
this.hashes = new ArrayList<LinkedList<String>>();
for (int i = 0; i < size; i++) {
hashes.add(new LinkedList<String>());
}
this.collisionCounter = 0;
this.longest = 0;
this.size = size;
}
public int getCollisionCounter() {
return collisionCounter;
}
public int size() {
return this.size;
}
public int getLongest() {
return this.longest;
}
//grows array to a new size
public void grow(int newSize, int numElements) {
ArrayList<LinkedList<String>> oldHashes = new ArrayList<LinkedList<String>>(this.hashes);
this.hashes = new ArrayList<LinkedList<String>>();
this.collisionCounter = 0;
this.longest = 0;
this.size = newSize;
for (int i = 0; i < this.size; i++) {
hashes.add(new LinkedList<String>());
}
for (int i = 0; i < oldHashes.size(); i++) {
LinkedList<String> currentList = oldHashes.get(i);
for (int q = 0; q < currentList.size(); q++) {
this.insert(currentList.get(q));
}
}
if (this.longest > 20 || this.load(numElements) > .75) {
newSize = newSize + 20;
newSize = this.findPrime(newSize);
this.grow(newSize, numElements);
}
}
//inserts into hashtable keeps track of collisions and the longest chain
public void insert(String element) {
int index = this.hash(element);
this.hashes.get(index).add(element);
if (index < this.size) {
if (this.hashes.get(index).size() > 1) {
this.collisionCounter++;
if (this.hashes.size() > this.longest) {
this.longest++;
}
}
}
}
//finds the first prime number that is larger that the starting number or the original number if that is prime
//if used to find a new table size the int in the parameters will need to be incremented
public int findPrime(int startInt) {
int newNum = startInt++;
boolean isFound = false;
while (!isFound) {
boolean isPrime = true;
int divisor = 2;
while (isPrime && divisor < newNum / 2) {
if (newNum % divisor == 0) {
isPrime = false;
} else {
divisor++;
}
}
if (isPrime) {
isFound = true;
} else {
newNum++;
}
}
return newNum;
}
public double load(int numElements) {
return (numElements + 0.0) / (this.size + 0.0); //int division may be a problem
}
//helper method for insert and search creates hash value for a word
public int hash(String ele) {
char[] chars = ele.toCharArray();
double hashCode = 0;
for (int i = 0; i < chars.length; i++) {
hashCode += chars[i] * Math.pow(5521, chars.length - i);
}
if (hashCode < 0) {
hashCode = hashCode + this.size;
}
return (int) (hashCode % this.size);
}
//method to search for a word in hashtable finds a string in the hastable return true if found false if not found
public boolean search(String goal) {
int index = this.hash(goal);
LinkedList<String> goalList = this.hashes.get(index);
for (int i = 0; i < goalList.size(); i++) {
if (goalList.get(i).equals(goal)) {
return true;
}
}
return false;
}
}
import java.util.ArrayList;
导入java.util.LinkedList;
公共类哈希表{
私有数组列表散列;
private int collisionCounter;//已发生的冲突总数
private int longest;//长度冲突
私有整数大小;
公共哈希表(整数大小){
this.hashes=新的ArrayList();
对于(int i=0;i20 | |此.load(numElements)>0.75){
新闻大小=新闻大小+20;
newSize=this.findprome(newSize);
这个。增长(新闻化,numElements);
}
}
//向哈希表中插入可以跟踪冲突和最长链
公共void插入(字符串元素){
int index=this.hash(元素);
this.hashes.get(index.add)(元素);
如果(索引<此大小){
if(this.hashes.get(index.size()>1){
这个.collisionCounter++;
if(this.hashes.size()>this.longest){
这个.最长的++;
}
}
}
}
//查找大于起始数或原始数(如果是素数)的第一个素数
//如果用于查找新的表大小,则需要增加参数中的int
公共int findPrime(int startInt){
int newNum=startInt++;
布尔值isFound=false;
而(!isFound){
布尔值isPrime=true;
整数除数=2;
while(isPrime和除数
下面是实际构建表的方法的代码,它获取所有单词的arrayList并将它们插入数组(在执行时对它们进行散列),检查加载/冲突长度,并在需要时对其进行增长
public static HashTable createHash(ArrayList<String> words) {
int initSize = findPrime(words.size());
HashTable newHash = new HashTable(initSize);
for (int i = 0; i < words.size(); i++) {
newHash.insert(words.get(i));
if (newHash.load(i) > .75 || newHash.getLongest() > 20) {
int size = newHash.size();
size = size + 25;
int newSize = findPrime(size);
newHash.grow(newSize, i);
}
}
return newHash;
}
公共静态哈希表createHash(ArrayList单词){
int initSize=findprome(words.size());
HashTable newHash=新的HashTable(initSize);
for(int i=0;i0.75 | | newHash.getLongest()>20){
int size=newHash.size();
尺寸=尺寸+25;
int newSize=findprome(大小);
newHash.grow(newSize,i);
}
}
返回newHash;
}
抱歉,这是很多代码需要整理,但我无法找出我在这里做错了什么,也不知道如何将其浓缩。非常感谢您的帮助 在您的
insert
方法中,您应该使用以下内容来跟踪最长的链
if(this.hashes.get(index).size() > this.longest) {
this.longest = this.hashes.get(index).size();
}
这就解释了为什么它会运行几秒钟,然后点击一个stackOverflowerError
,因为longest
的值没有改变(因为this.hashes.size()
不会改变)不会改变)