在声明变量而不是给它一个基值时,为什么要指定nil?

时间:2015-07-03 19:25:36

标签: ruby-on-rails ruby

我在Ruby中一直在做一些练习问题,这经常出现。

让我们说我试图解决整数数组中的第三个最大整数

def third_greatest(nums)
  first = 0
  second = 0
  third = 0
  i = 0

  while(i < nums.length)
     if nums[i] > first
       third = second
       second = first
       first= nums[i]
     elsif nums[i] > second
       third = second
       second = nums[i]
     elsif nums[i] > third
       third = nums[i]
     end
   i+=1
 end
 return third
end

此代码确实满足提供的测试用例

但是给出的解决方案用nil初始化变量,如果变量为nil,则在每个if语句中进行额外的检查

def third_greatest(nums)
  first = nil
  second = nil
  third = nil

  idx = 0
  while idx < nums.length
    value = nums[idx]
    if first == nil || value > first
      third = second
      second = first
      first = value
    elsif second == nil || value > second
      third = second
      second = value
    elsif third == nil || value > third
     third = value
    end
   idx += 1
  end

  return third
end

在什么情况下我的代码不正确?哪种代码更好实践?在案例2中感觉更麻烦,虽然我可以想象有一些边缘情况,我的解决方案可能无法正常工作。

3 个答案:

答案 0 :(得分:1)

您的代码不适用于负数。和

{{1}}

这就是在第二种情况下进行零检查的原因

答案 1 :(得分:1)

当第三个最大整数小于0或数组小于3时,您的代码不正确。

第二个代码更好,虽然它仍然不好。使第二个代码更像Rubyish可以是这样的:

def third_greatest(nums)
  a = []
  nums.each do |i|
    if    !a[0] || i > a[0] then a.insert(0, i)
    elsif !a[1] || i > a[1] then a.insert(1, i)
    elsif !a[2] || i > a[2] then a.insert(2, i)
    end
  end
  a[2]
end

答案 2 :(得分:0)

说nums是[0,-5,8,-15]。零会被忽略,所以你有第三大的-15,而不是-5应该是。

通常,nil更好地分配,就好像你分配了一个可以由你的代码赋值的任意值,逻辑/流程可能会中断。

IMO上面两个版本的代码都很糟糕。

只需nums.sort.reverse[2]即可获得您的价值,或者您想获得第三大独特价值:nums.uniq.sort.reverse[2]