Сравнение Integer с nil не удалось в алгоритме пузырьковой сортировки

Я создаю алгоритм пузырьковой сортировки. Почему я получаю сообщение об ошибке при сравнении Integer с nil failed (ArgumentError)?

def bubble_sort(arr)

  arr.each_with_index do |i, j|    
    print arr[j]
    print arr[j+1]

    if arr[j] > arr[j+1]
      print "swap"
    end 
  end

  print arr

end

bubble_sort([4,3,78,2,0,2])

person markus902    schedule 28.04.2019    source источник
comment
Когда вы доберетесь до последнего элемента arr, j = arr.size-1 и i = arr[j]. Затем вы сравниваете arr[j] с arr[j+1]. Следовательно, последнее равно nil, поэтому вы сравниваете целое число с nil. (Предположительно, arr содержит целые числа.)   -  person Cary Swoveland    schedule 28.04.2019
comment
Даже когда вы решите свою проблему, ваш алгоритм не будет работать, потому что вы фактически не меняете местами элементы arr. С puts "swap" вы просто говорите, что вы есть. :-)   -  person Cary Swoveland    schedule 28.04.2019


Ответы (2)


Во-первых, вы просите сценарий прочитать индекс J+1, тогда как последний индекс может быть j. Или, другими словами, вы запрашиваете доступ к нулевому значению в массиве. Вы должны убедиться, что вы не пытаетесь получить доступ к элементу n+1 в вашем массиве. Просто проверьте и прервите цикл, если дойдете до последнего элемента:

break if arr.size-1 == j #j is the last index now 

Во-вторых, вы ничего не делаете в своем коде, кроме печати. Вы можете сделать что-то

temp = arr[j]
arr[j] = arr[j+1]
arr[j+1] = temp
person Ali Day    schedule 28.04.2019
comment
Спасибо, теперь это работает. Сценарий больше похож на упражнение. Теперь я действительно могу что-то с этим сделать :-) - person markus902; 28.04.2019
comment
Напомним, что при параллельном присваивании (также известном как множественное присваивание) вам не нужна переменная (temp). Просто arr[j], arr[j+1] = arr[j+1], arr[j]. Неверно сказать, что вы запрашиваете доступ к значению nil в массиве. Ведь массивы могут содержать nil элементов. Я полагаю, вы имеете в виду, что OP пытается индексировать элемент с индексом, который больше, чем индекс последнего элемента массива (arr.size-1), поэтому возвращается nil. Да, многословно, но такова жизнь. Наконец, я не думаю, что вы бы break вышли из цикла; у вас просто никогда не будет индекса за пределами границ. - person Cary Swoveland; 29.04.2019
comment
Спасибо @CarySwoveland. Что касается вашего второго пункта, вы говорите о чем-то подобном? arr.each_with_index do |element, index|; if arr.size-1 != index; arr[index], arr[index+1] = arr[index+1], arr[index]; end; end - person Ali Day; 29.04.2019

Элемент массива с индексом j+1 не может быть найден при переборе массива с .each_with_index. j+1 возвращает nil, а затем вы пытаетесь сравнить его с arr[j], что вызывает ошибку аргумента.

.each_with_index здесь бесполезно, так как вы используете только индексы. И вам нужно снова запустить проверку, если найдены несортированные значения.

Я предлагаю использовать цикл от 0 до последнего возможного значения индекса. Что-то вроде этого:

def bubble_sort(arr)
  index = 0

  while index < arr.size - 1 do
    if arr[index] > arr[index+1]
      arr[index], arr[index+1] = arr[index+1], arr[index]
      index = 0
    else
      index += 1
    end
  end

  print arr
end

bubble_sort([4,3,78,2,0,2]) # => [0, 2, 2, 3, 4, 78]
person Nataniele    schedule 12.07.2019