将整数值插入哈希表时ArrayIndexOutOfBoundsException

时间:2013-11-26 16:04:20

标签: java arrays indexoutofboundsexception

我不知道错误在哪里(插入表格)。它是我的代码的片段(插入到开放寻址哈希表中)。线性和双寻址都很好,但有了这个(二次函数寻址)它的错误

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;
}

3 个答案:

答案 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

除此之外,当您插入的密钥为负数时,您也会得到负面索引。