如何从数组中删除后跟相同元素的元素

时间:2017-06-19 02:03:32

标签: ruby

我有一个数组。索引463有两个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

有谁能告诉我如何纠正这个问题?

3 个答案:

答案 0 :(得分:4)

要“模拟”这种selection sort,您可以尝试使用从0开始的范围迭代数组作为索引为0的值,并将数组的长度作为最后一个元素。此范围不会采用最后一个数组值。

使用each,您可以从创建的范围访问每个值,然后,使用该“索引”,您可以创建一个新范围,同样不使用最后一个元素,但是时间提前一步,即为a的当前值加1。这样,使用each您可以访问之前创建的“父”和“子”范围内的ab

现在,您可以检查数组中索引为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后,您可以通过使用tempa索引交换数组值来“跳过”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