【问题标题】:Comparison of Integer with nil failed (ArgumentError) while solving Insertion Sort with Ruby用 Ruby 解决插入排序时整数与 nil 的比较失败 (ArgumentError)
【发布时间】:2021-11-11 15:30:40
【问题描述】:

以下是更新后的代码:

def insertion_sort(list)
  num = list.length
  for i in (0..(num-2))
    if list[i] > list[i+1] && i == 0
      list[i], list[i+1] = list[i+1], list[i]
      i+=1
    elsif list[i] == list[i+1]
      i+=1
    elsif list[i] > list[i+1] && i > 0
      len = (list[0..(i+1)].length)
      list2 = list[0..(i+1)]
      list = list - list2
      count = 0
      while count <= len+1
        if list2[len-1] < list2[len-2]
           list2[len-2],list2[len-1]= list2[len-1],list2[len-2] 
        elsif  list2[len-1] == list2[len-2]
          count+=1
          len-=len
        else
         count+=1
         len-=1 
        end
      end
       list = list2 + list  
    end
  end
   list
end

p insertion_sort([2,1,4,8,7,3,100,99,8])
p insertion_sort([2,1,4,8,8,7,3,100,99])
p insertion_sort([3790,780,780,1,55])

总结:

  1. 如果两个相同的整数彼此相邻,则代码有效:[2,1,4,8,8,7,3,100,99] 并且数组大小 > 5。
  2. 如果两个相同的整数在随机位置:[2,1,4,8,7,3,100,99,8]。会出现以下错误 aaa.rb:4:in `>': Integer 与 nil 的比较失败 (ArgumentError)

第 4 行代码为:if list[i] > list[i+1] && i == 0

解决1.我将while循环更改为“while count

有谁知道如何解决这个问题? 提前致谢!

【问题讨论】:

  • 代码对我来说很好(输出为 [1, 2, 3, 4, 7, 8, 8, 99, 100])。你又在运行哪个版本的 Ruby?
  • @CormacMulhall 当前使用 Ruby 3.0.0p0。您在哪个版本上测试了代码?谢谢!
  • 用 3.0.2 和 2.7.4 测试(3 和 2 分支的最新版本)。该错误暗示 i 超出列表范围,根据您的代码,我不明白为什么会发生这种情况。您确定您正在运行的代码与您在此处粘贴的代码没有什么不同?
  • @CormacMulhall 实际上 [2,1,4,8,8,7,3,100,99] 上面的数组可以正常工作。但是我测试了另一个更极端的数组 [3790,1,780,55,23,50,1111,60,50],我最终得到了 ArgumentError。 “整数与零的比较失败”。无法弄清楚为什么它会超出范围......

标签: ruby insertion-sort argument-error


【解决方案1】:

感谢 cmets 的澄清。我现在看到了问题。

这里是交换算法

elsif list[i] > list[i+1] && i > 0
  len = (list[0..(i+1)].length)
  list2 = list[0..(i+1)]
  list = list - list2
  count = 0
  while count <= len+1
    ...

您正试图将数组一分为二。你得到list2,它是数组的前半部分,然后尝试从list减去 list2 得到后半部分。

在此处使用 subtract 的问题在于,如果您有重复项,它将删除它们并使您的列表太短。

在示例[3790,1,780,55,23,50,1111,60,50] 中,您应该在第一个数组中有一个50,在后半部分有一个50

但使用减法会删除其中一个50

当您将两个临时列表重新添加在一起时,您现在缺少一个元素(缺少的 50),当您到达数组末尾并尝试访问第 9 个元素时,您会遇到越界错误已经不存在了。

这里不使用减法,只需使用与 list2 相同的方法。

list2 = list[0..(i+1)] # All elements in list from position 0 to i+1
list = list[(i+2)..-1] # All elements in list from position i+2 to end of list

现在listlist2 只是原始列表拆分,当您将它们重新添加在一起时,它们应该是相同的长度

def insertion_sort(list)
  num = list.length
  for i in (0..(num-2))
    if list[i] > list[i+1] && i == 0
      list[i], list[i+1] = list[i+1], list[i]
      i+=1
    elsif list[i] == list[i+1]
      i+=1
    elsif list[i] > list[i+1] && i > 0
      len = (list[0..(i+1)].length)
      list2 = list[0..(i+1)]
      list = list[(i+2)..-1]
      count = 0
      while count <= len+1
        if list2[len-1] < list2[len-2]
           list2[len-2],list2[len-1]= list2[len-1],list2[len-2] 
        elsif  list2[len-1] == list2[len-2]
          count+=1
          len-=len
        else
         count+=1
         len-=1 
        end
      end
       list = list2 + list  
    end
  end
   list
end

p insertion_sort([2,1,4,8,7,3,100,99,8])
p insertion_sort([2,1,4,8,8,7,3,100,99])
p insertion_sort([3790,780,780,1,55])

【讨论】:

  • 感谢科马克!我正要测试列表减法和加法,但幸运的是我先读了你的答案。非常彻底的100!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-23
  • 2022-11-01
  • 2010-12-26
  • 2015-01-15
  • 2014-02-01
  • 2017-01-31
相关资源
最近更新 更多