Итак, я потратил немало времени, пытаясь понять, что не так с моим кодом. У меня есть примерная программа, в которой я сравнивал свою работу, которая работает. Мой код структурирован по-разному (это все в одном методе, по просьбе моего профессора), чем пример (который использует два метода). Я должен создать рекурсивное решение с разделителями и победами для подсчета инверсий в массиве int.Манипуляция и рекурсия Java Array
Я проиграл, почему пример программы поддерживает манипуляции с входным массивом во всей рекурсии, а мой нет. Я знаю, что Java - это пропускная способность, поэтому я смущен, почему работает этот пример. Любая помощь со мной в понимании различий в этих решениях будет очень признательна! Благодаря!
Пример кода с двумя методами - слияния и invCounter:
public static long merge(int[] arr, int[] left, int[] right) {
int i = 0, j = 0, count = 0;
while (i < left.length || j < right.length) {
if (i == left.length) {
arr[i+j] = right[j];
j++;
} else if (j == right.length) {
arr[i+j] = left[i];
i++;
} else if (left[i] <= right[j]) {
arr[i+j] = left[i];
i++;
} else {
arr[i+j] = right[j];
count += left.length-i;
j++;
}
}
return count;
}
//the recursive function
public static long invCounter(int[] arr) {
int sum = 0;
if (arr.length < 2)
return 0;
int m = (arr.length + 1)/2;
int left[] = Arrays.copyOfRange(arr, 0, m);
int right[] = Arrays.copyOfRange(arr, m, arr.length);
sum += invCounter(left);
sum += invCounter(right);
sum += merge(arr, left, right);
return sum;
}
Моя реализация одного метода (попытка):
public static int invCounter(int ranking[]) {
int sum = 0;
int result[] = new int[ranking.length];
int resIndx = 0;
if (ranking.length < 2) {
return 0; //base case
}
//divide
int left[] = Arrays.copyOfRange(ranking, 0, ranking.length/2);
int right[] = Arrays.copyOfRange(ranking, ranking.length/2,
ranking.length);
sum += invCounter(left);
sum += invCounter(right);
int i = 0, j = 0;
while (i < left.length || j < right.length) {
if (i == left.length) {
//i empty, just add j
result[resIndx++] = right[j++];
}
else if (j == right.length) {
//j empty, just add i
result[resIndx++] = left[i++];
}
else if (right[j] < left[i]) {
//inversion
result[resIndx++] = right[j++];
sum += left.length - i;
}
else {
//no inversion
result[resIndx++] = left[i++];
}
}
ranking = Arrays.copyOf(result, result.length);
return sum;
}
Почему пример программы в состоянии поддерживать обновленный массив через рекурсию, а мой нет?
UPDATE (10/22/15): Так я обнаружил, что я могу получить правильные результаты, если я заменю result
с ranking
и просто модифицировать этот массив напрямую. Мой вопрос сейчас, хотя почему я не могу использовать массив результатов для временного хранения результатов, а затем скопировать их в массив ранжирования (аргумента) в конце? Мне кажется, что это будет делать то же самое, что и ранжирование значений, однако изменения в ranking
не отражаются, если я изменю его в конце.
Arrays.copyOf всегда создает новый массив и копирует содержимое оригинальных массивов в него. Таким образом, вы не копируете результаты массива результатов [] в ранжирование [], вы просто создаете новый массив и назначаете его своей ранговой переменной. Но исходное ранжирование [] не изменяется. –