【问题标题】:Ruby infinite loop in bubble sort algorithm冒泡排序算法中的Ruby无限循环
【发布时间】:2016-08-31 08:02:31
【问题描述】:

我已经用 Ruby 构建了基本的冒泡排序算法,没有任何问题。代码如下:

def bubble_sort(arr)
 swapped=true
 while swapped
    swapped=false
    for j in 0..arr.length-2 do
      if arr[j]>arr[j+1]
        arr[j], arr[j+1] = arr[j+1], arr[j]
        swapped=true
      end
    end
 end
arr
end

现在,我正在尝试实现相同的方法,但具有接受代码块的功能。代码块部分工作正常,但是当没有提供代码块时,该方法应该像上面那样工作,虽然在我看来逻辑上相同,但由于某种原因,它进入了无限循环:

在“除非”这一行,如果需要,它会检查条件和交换位置,并会跳过收益率部分。我尝试通过rdebugger一步步调试,但找不到原因。

def bubble_sort_by(arr)
  swapped = true
  while swapped
    swapped=false
    for i in 0..arr.length-2 do
      unless block_given?
        arr[i], arr[i+1] = arr[i+1], arr[i] if arr[i] < arr[i+1]
        swapped=true
      end #unless
    if block_given?
      if yield(arr[i], arr[i+1])>0
        arr[i], arr[i+1] = arr[i+1], arr[i]
        swapped=true
      end #if yield
    end #if block_given?
    end #for
  end #while
puts arr
return arr
end

【问题讨论】:

    标签: ruby algorithm loops infinite-loop bubble-sort


    【解决方案1】:

    快速回答:

    arr[i], arr[i+1] = arr[i+1], arr[i] if arr[i] < arr[i+1]
    swapped=true
    

    应替换为:

    if arr[i] < arr[i+1]
      arr[i], arr[i+1] = arr[i+1], arr[i]
      swapped=true
    end
    

    发生的情况是您总是swapped 设置为true,即使元素没有交换。所以你陷入了无限循环。

    现在进行一些代码清理...首先,而不是编写:

    if(foo)
      # ...
    end
    unless(foo)
      # ...
    end
    

    让我们让它成为if/else 声明:

    def bubble_sort_by(arr) 
      swapped = true 
    
      while swapped 
        swapped=false 
        for i in 0..arr.length-2 do 
          if block_given? 
            if yield(arr[i], arr[i+1])>0 
              arr[i], arr[i+1] = arr[i+1], arr[i] 
              swapped=true 
            end 
          else 
            if arr[i] < arr[i+1] 
              arr[i], arr[i+1] = arr[i+1], arr[i] 
              swapped=true 
            end 
          end 
        end #for 
      end #while 
    
      return arr 
    end
    

    您可以按照@Aetherus 的建议进一步重构它以删除while 循环,但我认为您会很高兴看到实际的错误已修复。

    【讨论】:

    • 感谢您抽出宝贵时间,Tom,您不仅回答了我的问题,还为像我这样的新手提供了非常有价值的提示。祝你一切顺利!
    【解决方案2】:

    你的代码有太多block_given?,我不明白你为什么需要布尔变量swapped

    这是我的冒泡排序版本(因为它对数组进行了适当的排序,所以我给了它一个名字)。

    def bubble_sort!(arr, &compare)
      # Provide a default comparison algorithm
      compare ||= proc {|a, b| a <=> b}
    
      (1...arr.length).each do |i|
        (0...i).each do |j|
          arr[i], arr[j] = arr[j], arr[i] if compare.call(arr[i], arr[j]) < 0
        end
      end
    
      arr
    end
    

    【讨论】:

    • 感谢您的周密回复,我知道我离最佳实践还很远,需要更多学习才能适应所有这些。感谢您的反馈。
    猜你喜欢
    • 2012-09-17
    • 1970-01-01
    • 1970-01-01
    • 2018-05-05
    • 2017-06-29
    • 1970-01-01
    • 2015-01-17
    • 1970-01-01
    • 2014-04-17
    相关资源
    最近更新 更多