Поменяйте местами первые два элемента в массиве, которые не отсортированы - PullRequest
0 голосов
/ 28 сентября 2019

Я пытаюсь написать код, который ищет первые два элемента в массиве, которые вышли из строя, и заменяет их.Я написал этот код, но только при печати запускаю 3.Может кто-нибудь помочь мне переписать мой код, чтобы он работал?

arr = [5, 22, 29, 39, 19, 51, 78, 96, 84]
i = 0
while (i < arr.size - 1 and arr[i] < arr[i + 1])
  i = i + 1
end
puts i
arr[i] = arr[i + 1]
arr[i + 1] = arr[i]

Ответы [ 3 ]

5 голосов
/ 28 сентября 2019

Вы можете написать следующее:

arr = [5, 22, 29, 39, 19, 51, 78, 96, 84]

i = (0..arr.size-2).find { |i| arr[i] > arr[i+1] }
  #=> 3
arr[i], arr[i+1] = arr[i+1], arr[i] unless i.nil?
  #=> [19, 39]
arr
  #=> [5, 22, 29, 19, 39, 51, 78, 96, 84] 
3 голосов
/ 28 сентября 2019

Проблема с вашим текущим кодом:

arr[i] = arr[i + 1]
arr[i + 1] = arr[i]

Где вы установите arr[i] равным arr[i + 1], затем измените содержимое arr[i + 1] на arr[i] (которое установлено на arr[i + 1]).Это устанавливает оба элемента на содержание arr[i + 1].Вы можете использовать временную переменную для хранения предыдущего значения arr[i].

tmp = arr[i]
arr[i] = arr[i + 1]
arr[i + 1] = tmp

Более чистый способ сделать это - использовать множественное присваивание .

arr[i], arr[i + 1] = arr[i + 1], arr[i]

Что устраняет необходимость во временной переменной.


Получив вдохновение из ответов Cary Swoveland и iGian .Вот еще один переработанный способ поиска индекса и обмена значениями.

arr = [5, 22, 29, 39, 19, 51, 78, 96, 84]
i = arr.each_cons(2).find_index { |a, b| a > b }
arr[i, 2] = arr[i, 2].reverse if i

arr #=> [5, 22, 29, 19, 39, 51, 78, 96, 84]
1 голос
/ 28 сентября 2019

Вы можете использовать Enumerable # each_cons в сочетании с Enumerable # each_winth_index для получения пар и их индексов (*).Затем Enumerable # find первый индекс пары в обратном порядке, Object # затем измените исходный массив, вставив замененную пару:

arr = [1,2,3,5,4]

arr.each_cons(2).with_index.find { |(a, b), i| a > b }
   .then { |e, i| arr[i..i+1] = e.reverse if i }

arr
#=> [1, 2, 3, 4, 5]

(*) Как это работает:

arr.each_cons(2).with_index.to_a
#=> [[[1, 2], 0], [[2, 3], 1], [[3, 5], 2], [[5, 4], 3]]

Примечание: используйте Object # yield_self для более старого Ruby вместо Object # затем

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...