我有一个数组。索引46
和3
有两个7
:
arr = [7, 68, 42, 46, 9, 91, 77, 46, 86, 1]
我的任务是使用selection sort对此数组进行排序,但不是.sort
。结果应该是:
[1, 7, 9, 42, 46, 46, 68, 77, 86, 91]
所以,我在.rb
文件中执行了此操作:
def insertion_sort(arr)
length = arr.size
arr.each_with_index do |number, index|
puts "Now the index is #{index}"
current_minimum = arr.last(length - index).min
puts "Now the current_minimum in last#{length - index} elements is #{current_minimum}"
arr.delete(current_minimum)
arr.insert(index, current_minimum)
end
end
arr = [7, 68, 42, 46, 9, 91, 77, 46, 86, 1]
answer = insertion_sort(arr)
puts answer.to_s
我执行了这个文件,然后得到了这个:
[1, 7, 9, 42, 68, 91, 77, 86, 46]
如果我删除了一个46
,就会出现这个问题:
[1, 7, 9, 42, 46, 68, 77, 86, 91]
当数组中出现多个单个值时,我的代码不起作用。当each_with_index
块转到索引3
时,它会从数组的其余部分删除所有46
。
有谁能告诉我如何纠正这个问题?
答案 0 :(得分:4)
要“模拟”这种selection sort
,您可以尝试使用从0开始的范围迭代数组作为索引为0的值,并将数组的长度作为最后一个元素。此范围不会采用最后一个数组值。
使用each
,您可以从创建的范围访问每个值,然后,使用该“索引”,您可以创建一个新范围,同样不使用最后一个元素,但是时间提前一步,即为a
的当前值加1。这样,使用each
您可以访问之前创建的“父”和“子”范围内的a
和b
。
现在,您可以检查数组中索引为b
的元素的值是否小于数组中索引为a
的元素的值,如果此验证为true,则创建一个temp
变量带有索引为b
的数组中元素的值,则数组中位置(索引)b
的元素将等于数组中的元素位置a
,最后位于a
的数组中的元素将等于之前创建的temp
变量。
最后返回作为参数传递的数组。
def insertion_sort(array)
(0...array.length).each do |a|
((a+1)...array.size).each do |b|
if array[b] < array[a]
temp = array[b]
array[b] = array[a]
array[a] = temp
end
end
end
array
end
arr = [7, 68, 42, 46, 9, 91, 77, 46, 86, 1]
p insertion_sort(arr)
# => [1, 7, 9, 42, 46, 46, 68, 77, 86, 91]
添加@MarkThomas后,您可以通过使用temp
和a
索引交换数组值来“跳过”b
变量:
def insertion_sort(array)
(0...array.length).map do |a|
((a+1)...array.size).each do |b|
array[a], array[b] = array[b], array[a] if array[b] < array[a]
end
end
array
end
答案 1 :(得分:0)
谢谢你们所有人。我改进了我的代码,看起来效果很好。这是代码:
def insertion_sort(arr)
length = arr.size
arr.each_with_index do |number, index|
current_minimum = arr.last(length - index).min
current_minimum_index = arr.last(length-index).index(current_minimum) + index # this insure it will delete the right element
arr.delete_at(current_minimum_index)
arr.insert(index, current_minimum)
end
end
arr = [7, 68, 42, 46, 9, 91, 77, 46, 86, 1]
answer = insertion_sort(arr)
puts "---------------------------------------------------------------"
puts "Finally we get #{answer.to_s}"
答案 2 :(得分:0)
要在Ruby中实现Selection Sort,您可以使用Kernel#loop
,小心地将obj
传递给break
,以获得正确的返回值。
arr = [7, 68, 42, 46, 9, 91, 77, 46, 86, 1]
sorted = loop.with_object([]) do |_,obj|
mindex = arr.index arr.min #find index of a minimum
obj << arr.delete_at(mindex) #push this minimum value to obj
break obj if arr.empty?
end
sorted #=> [1, 7, 9, 42, 46, 46, 68, 77, 86, 91]
有关详细信息,请参阅with_object
。