【发布时间】:2020-05-03 14:57:50
【问题描述】:
当元素数 N 大于 m/2 时,我试图调整数组的大小,m 是数组的初始大小,但它不起作用,我不明白为什么。这个数组应该像一个哈希表一样工作,所以我在每次插入之前都有一个哈希函数,在调整大小之后我想再次插入每个元素,并使用新的哈希值(m 值已更改)。这是错误:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at JumpHashing.resize(JumpHashing.java:55)
at JumpHashing.put(JumpHashing.java:50)
at JumpHashing.hashing(JumpHashing.java:40)
at JumpHashing.resize(JumpHashing.java:61)
at JumpHashing.put(JumpHashing.java:50)
at JumpHashing.hashing(JumpHashing.java:40)
at JumpHashing.resize(JumpHashing.java:61)
at JumpHashing.put(JumpHashing.java:50)
at JumpHashing.hashing(JumpHashing.java:40)
at JumpHashing.resize(JumpHashing.java:61)
at JumpHashing.put(JumpHashing.java:50)
at JumpHashing.hashing(JumpHashing.java:40)
at JumpHashing.resize(JumpHashing.java:61)
at JumpHashing.put(JumpHashing.java:50)
at JumpHashing.hashing(JumpHashing.java:40)
at JumpHashing.resize(JumpHashing.java:61)
at JumpHashing.put(JumpHashing.java:50)
at JumpHashing.hashing(JumpHashing.java:40)
at JumpHashing.resize(JumpHashing.java:61)
at JumpHashing.put(JumpHashing.java:50)
at JumpHashing.hashing(JumpHashing.java:40)
at JumpHashing.resize(JumpHashing.java:61)
at JumpHashing.put(JumpHashing.java:50)
at JumpHashing.hashing(JumpHashing.java:40)
at JumpHashing.resize(JumpHashing.java:61)
at JumpHashing.put(JumpHashing.java:50)
at JumpHashing.hashing(JumpHashing.java:40)
at JumpHashing.resize(JumpHashing.java:61)
at JumpHashing.put(JumpHashing.java:50)
at JumpHashing.hashing(JumpHashing.java:40)
at JumpHashing.resize(JumpHashing.java:61)
at JumpHashing.put(JumpHashing.java:50)
问题显然是调整大小,没有它(少于 23 个元素)它可以工作。
m的初始大小是23,这是实际代码(从algs4读取文件的类“In”):
public class JumpHashing{
private int m;
private int[] hashTable;
private static int id;
private int N;
public JumpHashing(){
m = 23;
hashTable = new int[m];
N = 0;
}
public void hashing(int value) {
int key = (value*11)%m;
put(key, value);
}
public void put(int key, int value) {
if(N <m/2) {
hashTable[key] = value;
N++;
} else {
m=m*2;
N=0;
resize(m);
}
}
public void resize(int m) {
int[] temp = new int[m];
for(int i=0; i<hashTable.length; i++) {
temp[i] = hashTable[i];
}
hashTable = new int[m];
for(int i=0; i<temp.length; i++) {
hashing(temp[i]);
}
}
public static void main(String[] args) {
JumpHashing hashT1 = new JumpHashing();
In file = new In("random.txt");
while(file.hasNextLine()) {
int value = Integer.parseInt(file.readLine());
hashT1.hashing(value);
}
for(int j=0; j<hashT1.hashTable.length; j++) {
StdOut.println("Key: "+j+" Value: "+hashT1.hashTable[j]);
}
}
}
【问题讨论】:
-
你能缩小代码吗(比如只有那些不起作用的部分)?另外,请给出错误出现的行!
-
你在这里创建了一个方法循环,所以你得到了stackoverflow。我没有仔细检查,但它看起来像散列调用put,调用resize和调用散列。
-
if(N <m/2) {,变量名称应以小写字母开头,并且比单个字符更具描述性,以提高可读性。 -
@AyushGarg 编辑时出现错误,但这就是问题所在,它只是关于放置、散列和调整大小的 3 种方法,就像一个无限循环
-
@TomStroemer 是的,但我现在真的不明白如何解决这个问题,就像 m 值永远不会停止增长,但如果没有调整大小,它就可以工作