2014-12-05 1 views
0

Я хочу написать метод, который находит медиану заданного массива целых чисел. Может кто-то объяснить, что не так/происходит в моем коде. Если массив имеет нечетное число целых чисел, он возвращает средний элемент из отсортированного массива. Если массив имеет четное число целых чисел, верните среднее из средних двух элементов из отсортированного массива. Ниже мой код, который продолжает застревать в бесконечном цикле.Ruby Method, который возвращает медианное целое число в массиве

def median_finder(array) 
    array.sort 
    element_count = array.length 

    if element_count % 2 != 0 
    while element_count != 1 do 
     array.shift 
     array.pop 
    end 

    return array 
    else element_count % 2 == 0 
    while element_count != 2 do 
     array.shift 
     array.pop 
    end 
    median = ((array[0] + array[1])/2) 
    return median 
    end 
end 

ответ

0

ваше время петли не изменяет переменную element_count, и поэтому условие цикла не изменится, зацикливания. element_count всегда остается значением размера исходного массива. Быстрое исправление приведено ниже:

... 
while element_count != 1 do 
    array.shift 
    array.pop 
    element_count = array.length 
end 
... 
while element_count != 2 do 
    array.shift 
    array.pop 
    element_count = array.length 
end 
+0

Следует отметить, что в то время как мой ответ фиксирует вашу конкретную проблему, это на самом деле не рубин-эск путь. Вы должны обязательно взглянуть на другие ответы на свой вопрос, особенно на использование Ури Агасси «инъекций» и использование Tin Man «нечетных?» И разбиение массива ('array [1 ..- 2]').Это примеры использования функций языка в ваших интересах и не решения проблем, которые уже решены. – afontaine

0

Ваше использование array.sort неверно. Это должно быть array.sort!.

Вместо:

if element_count % 2 != 0 

Использование:

if element_count.odd? 

Вместо:

array.shift 
array.pop 

Рассмотрим:

array = array[1..-2] 

else не принимает никаких условий. Это неправильно:

else element_count % 2 == 0 

Один из них будет работать:

else 

Или:

else # element_count % 2 == 0 

Будьте очень осторожны с этим видом логики:

element_count != 1 

Что если array имеет два e и вы их удаляете? element_count будет 0, и условный тест все равно не будет выполнен, поэтому код продолжит цикл.

Вместо этого используйте тест как:

element_count >1 
+0

Я не думаю, что использование 'array.sort!' Подходит в этом случае, так как порядок массива будет меняться после вызова 'median_finder'. 'array = array.sort' будет лучше. – ymonad

+0

'array.sort!' - это то же самое, что 'array = array.sort'. 'sort!' изменяет приемник. –

+0

@theTinMan - что ymonad говорит, что 'sort!' Повлияет на вызывающего метода 'median_finder'. 'array = array.sort' отличается, поскольку он создает новый массив (переопределяя параметр с помощью локальной переменной), а' sort! '_modifies_ сам параметр. –

0

Если вы уже знаете, количество элементов в массиве, было бы проще, используя математику (= делением длины на два), а зацикливание:

def median_finder(array) 
    array = array.sort 
    if array.length.odd? 
    array[array.length/2] 
    else 
    array[array.length/2 - 1, 2].inject(:+)/2.0 
    end 
end 

inject(:+) - рубиновый способ делать сумму. array[array.length/2 - 1, 2] принимает два элемента в середине массива, так что вы могли бы на самом деле заменить эту строку с чем-то вроде этого:

median1, median2 = array[array.length/2 - 1, 2] 
    (median1 + median2)/2.0 
+0

привет Ури, метод инъекций всегда меня смущает. не могли бы вы объяснить мне, что происходит в «другой» части вашего предложения. Я понимаю, что вы пытаетесь вызвать «медианный» элемент в четном массиве, но я не понимаю, что делает инъекция. Спасибо чувак. – jjc280

+0

@jomonavi - Я добавил еще несколько объяснений –