[英]Why does this merge sort produce an index out of bounds exception when sorting a second array at the same time?
我一直在研究一種合並排序算法,我最終想用它來對字符串數組進行排序。
理論是我對一個包含我想要排序的 ID 的數組進行排序,其順序與作為字符串的主數組相同,然后對 ID 數組進行排序並對字符串數組執行相同的操作,理論上對它們進行相同的排序方法。
例如,ID 值數組可以是 [1,2,3,4,5],主數組看起來像 ["Name, 1","Name, 2"]...
當我在不包含任何第二個數組部分的情況下運行算法時,它可以正常工作,這是輸出:
[0, 1, 1, 10, 12, 16, 18, 24, 26, 53, 53, 53, 100]
但是當我嘗試添加第二個數組操作時,我得到一個異常說:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 1 out of bounds for length 1
at s4001175.ct5057.flight.Booker.merge(Booker.java:250)
at s4001175.ct5057.flight.Booker.mergeSort(Booker.java:236)
at s4001175.ct5057.flight.Booker.mergeSort(Booker.java:232)
at s4001175.ct5057.flight.Booker.mergeSort(Booker.java:232)
at s4001175.ct5057.flight.FlightManagement.passengerStatus(FlightManagement.java:92)
at s4001175.ct5057.flight.FlightManagement.mainMenu(FlightManagement.java:53)
at s4001175.ct5057.flight.FlightManagement.main(FlightManagement.java:27)
代碼:
public void mergeSort(int[] flightIDArr, int arrLength, String[] actualArr) {
// Flattened array of bookings to 1d array
String[] flatArray = flattenArray(readBookings());
// If array does not need to be split as length is already 1
if (arrLength < 2) {
return;
}
// Middle of the array
int mid = arrLength / 2;
//Left array of length of half of the array
int[] left = new int[mid];
// Other half of split array, with arrLength-mid size to ensure that it works even if the array is an odd length
int[] right = new int[arrLength - mid];
//Mirrored version of previous lines but for string array of what we actually want to sort (booking info)
String[] actualLeft = new String[mid];
// Same as above but right side
String[] actualRight = new String[arrLength - mid];
// for the elements in left array
for (int i = 0; i < mid; i++) {
// filling the left arrays with the info from the full array
left[i] = flightIDArr[i];
actualLeft[i] = flatArray[i];
}
// for elements in right array
for (int i = mid; i < arrLength; i++) {
// filling the right arrays with the info from the full array
right[i - mid] = flightIDArr[i];
actualRight[i - mid] = flatArray[i];
}
//recursively calls the mergesort algorithm to split the arrays as small as possible
mergeSort(left, mid, actualLeft);
mergeSort(right, arrLength - mid, actualRight);
//re merges the split arrays
merge(flightIDArr,actualArr, left, right, mid, arrLength - mid, actualLeft,actualRight);
}
//Method to merge all the split arrays
public void merge(
int[] flightIDArr, String[] actualArr, int[] leftArr, int[] rightArr, int left, int right, String[] actualLeft, String[] actualRight) {
//setting up variables for looping
int i = 0, j = 0, k = 0;
//
while (i < left && j < right) {
if (leftArr[i] <= rightArr[j]) {
flightIDArr[k++] = leftArr[i++];
actualArr[k++] = actualLeft[i++];
}
else {
flightIDArr[k++] = rightArr[j++];
actualArr[k++] = actualRight[j++];
}
}
while (i < left) {
flightIDArr[k++] = leftArr[i++];
actualArr[k++] = actualLeft[i++];
}
while (j < right) {
flightIDArr[k++] = rightArr[j++];
actualArr[k++] = actualRight[j++];
}
// System.out.println(Arrays.toString(actualArr));
System.out.println(Arrays.toString(flightIDArr));
}
我已經嘗試使用 IntelliJ 中的調試器運行程序,並且當從第 250 行開始產生異常時,這些是所涉及的變量的值:
leftArr: 0:0
actualLeft:
0:
"Booking Number: 1
Flight Number: 000
Passenger Name: Test Name
Seat Number: 1
Seat Class: First"
所以看起來當代碼中的這個階段到達時,它試圖在這些數組中設置超出其范圍的值,但是在不涉及第二個數組的情況下運行算法時不會發生這種情況,盡管在線上發生了同樣的情況249,在哪里
flightIDArr[k++] = leftArr[i++];
叫做
編輯新代碼:
使用建議的答案,我更改了我的代碼,這似乎消除了錯誤,但是排序不再正常工作,甚至包括一些數字:
正確的輸出:
[0, 1, 1, 10, 12, 16, 18, 24, 26, 53, 53, 53, 100]
與新代碼的當前輸出:
[0, 1, 1, 1, 12, 16, 18, 18, 24, 53, 53, 53, 100]
如您所見,原始數據集中現在存在重復值和缺失值。
代碼:
public void mergeSort(int[] flightIDArr, int arrLength, String[] actualArr) {
// Flattened array of bookings to 1d array
String[] flatArray = flattenArray(readBookings());
// If array does not need to be split as length is already 1
if (arrLength < 2) {
return;
}
// Middle of the array
int mid = arrLength / 2;
//Left array of length of half of the array
int[] left = new int[mid];
// Other half of split array, with arrLength-mid size to ensure that it works even if the array is an odd length
int[] right = new int[arrLength - mid];
//Mirrored version of previous lines but for string array of what we actually want to sort (booking info)
String[] actualLeft = new String[mid];
// Same as above but right side
String[] actualRight = new String[arrLength - mid];
// for the elements in left array
for (int i = 0; i < mid; i++) {
// filling the left arrays with the info from the full array
left[i] = flightIDArr[i];
actualLeft[i] = flatArray[i];
}
// for elements in right array
for (int i = mid; i < arrLength; i++) {
// filling the right arrays with the info from the full array
right[i - mid] = flightIDArr[i];
actualRight[i - mid] = flatArray[i];
}
//recursively calls the mergesort algorithm to split the arrays as small as possible
mergeSort(left, mid, actualLeft);
mergeSort(right, arrLength - mid, actualRight);
//re merges the split arrays
merge(flightIDArr,actualArr, left, right, mid, arrLength - mid, actualLeft,actualRight);
}
//Method to merge all the split arrays
public void merge(
int[] flightIDArr, String[] actualArr, int[] leftArr, int[] rightArr, int left, int right, String[] actualLeft, String[] actualRight) {
//setting up variables for looping
int i = 0, j = 0, k = 0;
//
while (i < left && j < right) {
if (leftArr[i] <= rightArr[j]) {
flightIDArr[k] = leftArr[i];
actualArr[k++] = actualLeft[i++];
}
else {
flightIDArr[k] = rightArr[j];
actualArr[k++] = actualRight[i++];
}
}
while (i < left) {
flightIDArr[k] = leftArr[i];
actualArr[k++] = actualLeft[i++];
}
while (j < right) {
flightIDArr[k] = rightArr[j];
actualArr[k++] = actualRight[j++];
}
// System.out.println(Arrays.toString(ActualArr));
System.out.println(Arrays.toString(flightIDArr));
// System.out.println(" Actual Array: \n \n " +(Arrays.toString (actualArr)));
}
當您使用k++
j++
等時,您會增加變量。 您對左右數組都執行此操作。 但你可能只想做一次,而不是兩次。
你想替換這樣的代碼:
if (leftArr[i] <= rightArr[j]) {
flightIDArr[k++] = leftArr[i++];
actualArr[k++] = actualLeft[i++];
}
有了這個:
if (leftArr[i] <= rightArr[j]) {
flightIDArr[k] = leftArr[i];
actualArr[k++] = actualLeft[i++];
}
或這個:
if (leftArr[i] <= rightArr[j]) {
flightIDArr[k] = leftArr[i];
actualArr[k] = actualLeft[i];
k++; i++;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.