2016-06-15 6 views
0

Учитывая последовательность целых чисел, как я могу найти среднее значение с помощью подхода divide and conquer? Я должен написать метод «double avg (int [] a, int l, int r)», который находит среднее значение в массиве A, охватывающее от «l» до «r» в качестве домашней работы, но я получаю StackOverflowError на первый рекурсивный вызов - не во втором, хотя! - моего кода, и я не могу понять, почему. Кроме того, я уверен, что это не дает мне истинного среднего значения, но я не нашел возможности проверить среднее значение последовательности, используя разделение и победить. Вот мой код:Среднее число целых чисел, использующих divide и conquer

public class Average { 
public static void main(String[] args) { 

    int[] A = {2, 4, 6, 8, 10, 12, 14, 16, 18, 20}; 
    int l = 0; 
    int r = A.length-1; 
    System.out.println("Average of the array: "+averageCheck(A, l, r)); 

} 

public static double averageCheck(int[] A, int l, int r) { 
    if (l==r) { 
     return A[l]; 
    } 
    // Base Case: if there's just a single element it is the average of the array itself 

    int mid = (l+r)/2; 
    double avLeft = 0; 
    double avRight = 0; 

    avLeft = A[l]/r + averageCheck(A, l, mid); 
    avRight = A[mid+1]/r + averageCheck(A, mid+2, r); 

    double average = ((avLeft*mid) + (avRight * (r-mid))) /r; 

    return average; 

    } 
} 
+4

(не причина 'StackOverflowError') Среднее значение последовательности целых чисел является сумма делится на длину. Не делайте разделения до конца. Особенно не делятся на 'r', это бессмысленно. –

+1

Два подсказки: рассмотрите возможность написания модульного теста - такой код подходит для этого. Для самого исключения ... это обычно означает, что вы создали бесконечную рекурсию. Значение: в вашем коде отсутствуют условия для ** остановки ** рекурсии. Итак, первый шаг: добавьте операторы печати для своих переменных и/или запустите их в отладчике. – GhostCat

+0

@ AndyTurner, я где-то читал, что сумма элемента/длины для каждого элемента средняя, ​​поэтому я подумал, что это реально. Я попробую с нормальным средним сейчас, но еще сложнее представить его рекурсивно. – Monok

ответ

1

Ваш рекурсии не заканчивается, когда r == l + 1. В этом случае mid == l и во втором рекурсивном вызове mid+2 будет больше, чем r. Добавьте это в начале функции:

if(l > r) 
     return 0; 

примера, представьте l == 5 и r == 6, то mid будет иметь значение 5. Второй вызов будет averageCheck(A, 7, 6), как это mid+2 7. В этом вызове, условие будет l == r be false. Продолжайте в той же логике, и вы обнаружите, что рекурсия не закончится.

Я также думаю, что было бы лучше, если бы вы вычислили сумму рекурсивно и разделили на длину в конце.

Я полагаю, это решение:

public class Average { 
public static void main(String[] args) { 

    int[] A = {2, 4, 6, 8, 10, 12, 14, 16, 18, 20}; 
    System.out.println("Average of the array: "+average(A)); 

} 

public static double average (int[] A) { 
     return averageCheck(A, 0, A.length - 1)/A.length; 
} 

public static double averageCheck(int[] A, int l, int r) { 

if (l > r) 
    return 0; 

if (l==r) { 
    return A[l]; 
} 
// Base Case: if there's just a single element it is the average of the array itself 

int mid = (l+r)/2; 
double avLeft = 0; 
double avRight = 0; 

avLeft = averageCheck(A, l, mid); 
avRight = averageCheck(A, mid+1, r); 

double average = avLeft + avRight; 

return average; 

} 
} 
+0

Извините, вы можете объяснить это лучше? Я не понимаю, где «r = l + 1», или «mid == l». Второй вызов работает, но среднее значение не является ожидаемым, это просто двойник, созданный моей плохой математикой в ​​коде. – Monok

+0

Я добавил пример ответа. – AhmadWabbi

+0

@AhmadWabbi Диагноз правильный, предлагаемое решение не является идеальным. Я предпочел бы отсортировать диапазоны ** перед ** расщеплением. – biziclop

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