我的程序抛出 ArrayIndexOutOfBoundsException,但只是有时

My program throws an ArrayIndexOutOfBoundsException, but only sometimes

我在高中学习计算机科学 class,今天我们学习了选择排序课程。我写了一个程序(它可能很笨拙,但请耐心等待,我正在学习)并且它的工作原理是排序,但有时它会抛出 ArrayIndexOutOfBoundsException。只有某些时候。我不知道这是怎么可能的,因为我在整个程序中处理同一个数组,而且数组的长度是固定的。如果有人有一些见解,那将非常有帮助。

我认为错误与 int first = y[movedVariable]; 有关。但是,我不明白 movedVariable 是如何越界的,因为我很确定我编写的程序是 < 数组的长度。

public class selectionSort
{
    public static int[] array;
    public static int movedVariable = 0;
    public static void main()
    {
        array = new int[10];
        int x;
        for (int count = 0; count < array.length; count++)
        {
            if (count == 0)
            {
                x = (int)(Math.random()*100+2);
                array[count] = x;
            }
            else
            {
                x = (int)(Math.random()*100+2);
                for (int y = 0; y < count; y++)
                {
                    while(x == array[y])
                    {
                        x = (int)(Math.random()*100+2);
                    }
                }
                array[count] = x;
            }
        }
        sort(array);
    }

    public static void sort(int[] x)
    {
        int thing = 0;
        for(int hello = 0; hello < x.length; hello++)
        {   
            int part = x[thing];
            for ( int count = thing; count < x.length-1; count++)
            {
                if( part > x[count+1] )
                {
                    part = x[count+1];
                }
            }
            thing++;
            swap( x, part);
        }

        int f = 0;
        String output = "";

        for( int val : x )
        { 
            if (f%10 == 0)
            {output += "\n";}
            output += val + " "; 
            f++;
        }
        System.out.print(output);
    }

    public static int[] swap(int [] y, int num)
    {
        int count = 0;
        int index = 0;
        for ( count = 0; count < y.length; count++)
        {
            if (y[count] == num)
            {index = count;}
        }
        int first = y[movedVariable];
        y[movedVariable] = y[index];
        y[index] = first;
        movedVariable++;
        return y;
        }
    }

为了好玩,我 运行 你的代码进行了 1,000,000 次迭代并且没有越界异常,除非我在每次迭代之前没有将静态 movedVariable 清除为 0。

由于在前 10 次调用 swap() 之后 movedVariable 是静态的,它将是 10,如果再次调用 swap,您将得到索引超出范围。但是,这只有在每个 运行 多次调用 sort() 时才会发生。仅对需要在 class 实例之间保留的值使用静态。作为实例状态一部分的非静态。其他一切的局部变量。否则,您正在创建等待发生的错误雷区。

我重构了您的 class 以删除具有相同功能的变量。例如,您的 thing 和 movedVariable 以及 sort() 中的 hello 变量可以只是一个变量。尝试消除做同样事情的多个变量,例如瘟疫。它是不明显错误的来源。

此外,您将数组中的值传递给交换然后在数组中查找它以获取索引,这是浪费时间。只需传入索引即可交换。当您在两个不同的地方具有相同的值时,它还会为您的排序功能带来问题。 Swap 将使用它找到的最后一个。 sort() 应该处理数组中的重复值。这就解释了为什么你用唯一值初始化你的数组。你不应该那样做。实际上,您应该使用明确添加的重复代码来测试您的代码,以确保您的功能正常工作。

我将数组的打印从排序中移到了它自己的方法中。它对于在中间步骤进行调试非常有用,而不仅仅是在排序完成时。

我尽量保持变量名不变,逻辑不变,这样您就可以跟进变化。

public class Main
{
    public static void sort(int[] x)
    {
        for (int movedVariable = 0; movedVariable < x.length; movedVariable++)
        {
            int part = x[movedVariable];
            int index = movedVariable;

            for (int count = movedVariable; count < x.length - 1; count++)
            {
                if (part > x[count + 1])
                {
                    part = x[count + 1];
                    index = count + 1;
                }
            }

            swap(x, index, movedVariable);
        }

        printArray(x);
    }

    private static void printArray(int[] x)
    {
        int f = 0;
        String output = "";

        for (int val : x)
        {
            if (f % 10 == 0)
            {
                output += "\n";
            }
            output += val + " ";
            f++;
        }
        System.out.print(output);
    }

    public static int[] swap(int[] y, int index, int movedVariable)
    {
        int first = y[movedVariable];
        y[movedVariable] = y[index];
        y[index] = first;
        return y;
    }

    public static void main(String[] args)
    {
        int[] array = new int[10];
        int x = 0;
        for (int count = 0; count < array.length; count++)
        {
            for (int y = count; --y >= 0; )
            {
                do
                {
                    x = (int) (Math.random() * 100 + 2);
                }
                while (x == array[y]);
            }

            array[count] = x;
        }

        printArray(array);
        sort(array);
    }
}