2015-10-22 3 views
0

Итак, я потратил немало времени, пытаясь понять, что не так с моим кодом. У меня есть примерная программа, в которой я сравнивал свою работу, которая работает. Мой код структурирован по-разному (это все в одном методе, по просьбе моего профессора), чем пример (который использует два метода). Я должен создать рекурсивное решение с разделителями и победами для подсчета инверсий в массиве 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 не отражаются, если я изменю его в конце.

+0

Arrays.copyOf всегда создает новый массив и копирует содержимое оригинальных массивов в него. Таким образом, вы не копируете результаты массива результатов [] в ранжирование [], вы просто создаете новый массив и назначаете его своей ранговой переменной. Но исходное ранжирование [] не изменяется. –

ответ

0

Ваш метод не изменяет параметр ранжирования, вместо этого он создает новый массив (результат), и вы работаете над ним. Попробуйте прямо установить значение в массиве ранжирования, а не в массиве результатов, или просто установите переменную результата в ранжирование.

public static int invCounter(int ranking[]) { 
    int sum = 0; 
    int result[] = ranking; 
//other code... 

Edit: Или вы можете скопировать его содержимое, но не с Arrays.copyOf, потому что первый создает новый массив, а затем скопировать в него. Используйте вместо System.arraycopy, который копирует в существующий массив:

System.arrayCopy(result, 0, rankings, 0, result.length(); 
+0

Да, но я копирую массив в него внизу ... – Logan

+0

Нет, вы не копируете, вы перезаписываете его значение (вы назначаете ему новое значение). Вместо этого используйте System.arrayCopy, тогда это будет так. –

+0

Хорошо, но я также попытался скопировать его сам, просто перейдя по ссылке и установив рейтинг [i], чтобы получить результат [i]. Почему это тоже не сработает? Спасибо за помощь! – Logan

 Смежные вопросы

  • Нет связанных вопросов^_^