我不知道错误在哪里(插入表格)。它是我的代码的片段(插入到开放寻址哈希表中)。线性和双寻址都很好,但有了这个(二次函数寻址)它的错误
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -848
at openaddresshash.OpenAddressHash.insertKwadratowe(OpenAddressHash.java:101)
at openaddresshash.OpenAddressHash.main(OpenAddressHash.java:261)
Java Result: 1
我知道这一行有问题:
int index = ((start + (c1 * i) + (c2 * i * i))) % size;
但在我看来,它的一切都很好因为我的功能(索引)应该是:
h(k,i) = (h'(k) + c1*i + c2*i^2) mod m
where h'(k) = k mod m
我的代码:
for( int d = 25; d<=2500; d+=25)
{
int liczba=4*d;
OpenAddressHash hstb = new OpenAddressHash(liczba);
int jj=2*d;
hstb.AdresowanieKwadratoweDane(1, jj);
Losowania los = new Losowania(); // random values
los.Losowe(liczba);
for(int yy=0; yy<liczba; yy++)
{
hstb.insertKwadratowe(los.trzy[yy]);//trzy is a table with random values
if((yy%(Math.ceil(liczba/50)))==0)
{
AdresowanieKwadratowe.println( liczba+" "+yy+" "+hstb.s );
}
hstb.s=0;
}
}
static public class SLOT
{
public int key;
public STATUS stat;
public SLOT()
{
stat = STATUS.INVALID;
}
}
public void AdresowanieKwadratoweDane(int c1, int c2)
{
this.c1 = c1;
this.c2 = c2;
}
public OpenAddressHash(int n)
{
table = new SLOT[n];
for (int i = 0; i < table.length; i++)
{
table[i] = new SLOT();
}
}
public int insertKwadratowe(int key)
{
int size = table.length;
int start = key%size;
for (int i = 0; i < size; i++)
{
s++;
int index = ((start + (c1 * i) + (c2 * i * i))) % size;
if (table[index].stat == STATUS.INVALID ||
table[index].stat == STATUS.DELETED)
{
table[index] = new SLOT();
table[index].key = key;
table[index].stat = STATUS.OCCUPIED;
return index;
}
}
return -1;
}
public void AdresowanieKwadratoweDane(int c1, int c2)
{
this.c1 = c1;
this.c2 = c2;
}
答案 0 :(得分:1)
我可能不正确,但从查看计算索引的方式来看:
int index = ((start + (c1 * i) + (c2 * i * i))) % size;
如果start的值为0,则索引将等于size。虽然,尺寸代表数量。因此,除非您将其减少1,否则最终会遇到您所看到的异常。无论如何,对于第一次迭代。
答案 1 :(得分:1)
在insertKwadratowe
方法中看到异常,并且该方法中只有一个数组访问,问题必须在于计算索引,即此行:
int index = ((start + (c1 * i) + (c2 * i * i))) % size;
也许是开始,或者c1或c2是否定的,或者你的乘法可能会得到整数溢出,导致负数。
答案 2 :(得分:0)
考虑当我们有一个大小为2000的OpenAddressHash
时,插入会发生什么,并将c2变量设置为1000(正如你在d = 500时在外循环中所做的那样)。
然后i
可以升到1999年,在这种情况下你计算:
int index = ((start + (c1 * i) + (c2 * i * i))) % size;
子表达式
c2 * i * i
1000 * 1999 * 1999
给出了-298966296,因此你可能得到一个负面索引,除非start + (c1 *i)
能使它变好。但是没有任何迹象表明它会这样做,因为c1
总是1,据我所知,start
小于size
。
除此之外,当您插入的密钥为负数时,您也会得到负面索引。