合并两个已排序数组时发生的ArrayIndexoutofbound异常

3

我看到其他解决方案,比如这个,想知道我使用for循环的方法是否有问题。我不想使用while循环,因为其他人在他们的解决方案中使用了while循环。

package com.my.practice;

public class MedianOfTwoArrays {

    public static void main(String[] args) {
        // Given two sorted arrays of same size

        int[] a1 = {1,2,3,4,5,6};
        int[] a2 = {7,8,9,10,11,12};        

        int[] mergedArray = new int[a1.length + a2.length];

        for(int i=0 ; i < a1.length; i++){
            mergedArray[i] = a1[i];
        }

        //System.out.println("Length:"+2*(a1.length));

        for(int i= a1.length; i < 2 * (a1.length); i++) {
            mergedArray[i] = a2[i];
        }

        for(int i=0 ; i < 2*(a1.length); i++){          
            System.out.println("Part of Array: "+mergedArray[i]+ " Length is: "+mergedArray.length);
        }
    }
}

我收到了以下错误提示:
Length:12
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 6
    at com.my.practice.MedianOfTwoArrays.main(MedianOfTwoArrays.java:30)
5个回答

1

依赖于两个数组长度相同并不是一个好主意,因此我不会使用a1.length * 2。此外,您不能为原始数组和合并后的数组使用相同的索引,因为合并后的数组较长。

建议的解决方法:

int[] mergedArray = new int[a1.length + a2.length];

for(int i=0 ; i < a1.length; i++){
    mergedArray[i] = a1[i];
}

for(int i= 0 ; i < a2.length; i++){
    mergedArray[a1.length + i] = a2[i];
}

for(int i=0 ; i < mergedArray.length; i++){
    System.out.println("Part of Array: "+mergedArray[i]+ " Length is: "+mergedArray.length);
}

你忽略了主要问题:mergedArray[i] = a2[i];(这也出现在你的第一个代码示例中)将始终导致数组越界异常。 - Thomas Stets
@Thomas Stets 谢谢。我已经删除了第一个片段,因为第二个片段是正确的。 - Eran

1
你代码中的问题是第二个循环中使用 i 作为 a2 的索引。它对于 mergedArray 是有效的,但不适用于 a2

在第二个循环中使用 i-a1.length 作为索引。

for(int i= a1.length; i < 2 * (a1.length); i++) {
    mergedArray[i] = a2[i-a1.length];
}

或者使用三个索引: ijk。只是为了让您有一个想法。
int i, j, k = 0;

for (i = 0; i<a1.length; i++){
    mergedArray[k] = a1[i];
    k++;
}

for (j=0; j<a2.length; j++){
    mergedArray[k] = a2[j];
    k++;
}

1

在这行中:

for (int i= a1.length; i < 2 * (a1.length); i++) {
    mergedArray[i] = a2[i];
}

您正在尝试访问 a2[i],其中 i 的值从 6 到 11。由于 a2 是一个大小为 6 的数组,因此 a2[6]a2[7]...a2[11] 不存在。

在您的情况下,您想将值 a2[1] 插入到 mergedArray[6]a2[2] 插入到 mergedArray[7] 等。

您需要在右侧减去 a1.length

for (int i = a1.length; i < 2 * (a1.length); i++) {
    mergedArray[i] = a2[i - a1.length];
}

或者在左侧添加 a1.length
for (int i = 0; i < a1.length; i++) {
    mergedArray[i + a1.length] = a2[i];
}    

请选择更方便的一个。

1
错误(用于ArrayOutOfBoundException):
    for(int i= a1.length; i < 2 * (a1.length); i++) {
        mergedArray[i] = a2[i];  //Using 'i' incorrectly to access a2[i]
    }

“以上内容更正如下:”
    for(int i= 0; i < a2.length; i++) {
        mergedArray[i+a1.length] = a2[i];  //Using 'i' incorrectly to access a2[i]
    }

原因:

  • 这里的'i'将确保a2不会超出其大小,因为i的最大限制是a2.length。
  • 不要假设a2和a1的大小相等。在遍历a1时使用a1.length,在遍历a2时使用a2.length。
  • 可以添加安全(冗余)检查以确保(i+a1.length)不会超过mergedArray的大小。在这种情况下是冗余的,因为mergedArray的长度= a1.size + a2.size。

1
问题在于您正在为长度不同的数组使用相同的索引:
for(int i= a1.length; i < 2 * (a1.length); i++)
    mergedArray[i] = a2[i];

在最初的时候,i = 6a2数组的边界是0-5,但是a2[i]a2[6],超出了边界,这就导致了异常。
你可以通过使用System.arraycopy()来跳过这些循环。
 System.arraycopy(a1, 0, mergedArray,0, a1.length);
 System.arraycopy(a2, 0, mergedArray,a1.length, a2.length);

如果您仍然想使用循环,则可以使用另一个索引变量:
for(int i = 0, j = a1.length; i < (a2.length); i++, j++)
    mergedArray[j] = a2[i];

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接