【发布时间】:2019-11-07 05:46:20
【问题描述】:
问题
我正在尝试编写一个方法 (Array#bubble_sort),它接受一个可选的 proc 参数。
当给定一个proc时,该方法应该根据proc对数组进行排序。
当没有给定proc时,该方法应该按递增顺序对数组进行排序。
递归地,这在不添加 proc 的情况下可以正常工作,但是当给定一个未知的 proc 时,我无法找到一种方法将其作为参数正确地传递回来。
代码
class Array
def bubble_sort(&prc)
prc = Proc.new{|a,b| a <=> b} if !prc
self.each_with_index do |ele,idx|
if prc.call(self[idx],self[idx+1]) == 1
self[idx],self[idx+1] = self[idx+1], self[idx]
self.bubble_sort(&prc)
end
end
self
end
end
测试代码
[4, 12, 2, 8, 1, 14, 9, 25, 24, 81].bubble_sort返回[1, 2, 4, 8, 9, 12, 14, 24, 25, 81]的预期结果
[4, 12, 2, 8, 1, 14, 9, 25, 24, 81].bubble_sort { |a, b| a.to_s <=> b.to_s } 返回堆栈级别太深的错误,而不是[1, 12, 14, 2, 24, 25, 4, 8, 81, 9] 的预期结果
【问题讨论】:
-
我不知道问题出在哪里,但是如果您传递一个与默认 proc 相同的 proc,它就可以工作。所以这与proc的内容有关,而不是自定义proc的传递
-
哦,好的,我看到了差异。您的方法最终使用
81, nil调用proc。然而81 <=> nil == nil而'81' <=> nil.to_s == 1。这种差异一定是导致无限循环的原因 -
天哪,我花了很长时间才弄明白。谢谢!我通过在条件句末尾添加 t
&& idx+1 != self.length来修复。 -
完美,无论如何我都会写一个答案来解释它
-
&prc将prc转换为proc,但由于prc已经是proc,&prc与prc相同。我建议写bubble_sort!(prc = Proc.new{|a,b| a <=> b}),它给参数prc一个默认值。我将bubble_sort更改为bubble_sort!,因为您的代码修改了接收器。
标签: ruby algorithm recursion lambda proc