如何使用Ruby创建一个嵌套循环"正确的方法!"?

Dav*_*mez 14 ruby arrays loops ruby-on-rails

我正在学习Ruby,学习Berkeley的MOOC,而且在其中一些MOOC的作业中我们有一个练习:

定义方法sum_to_n?它接受一个整数数组和一个额外的整数n作为参数,如果整数数组中的任何两个元素总和为n,则返回true.根据定义,空数组应总和为零.

我已经创建了两种可以完成这项工作的方法,但是我对它们中的任何一种都不满意,因为我认为它们不是用Ruby方式编写的.我希望你们中的一些人可以帮助我学习哪种方法是正确的!

我制作的第一个方法each在两次迭代中都使用了这个方法,但我不喜欢这个方法的是每个数字都与其他数字相加,即使数字相同,也可以这样做:

arr[1, 2, 3, 4] => 1+1, 1+2, 1+3, 1+4, 2+1, 2+2, 2+3, 2+4, 3+1, 3+2... 4+3, 4+4
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,有很多重复的总和,我不希望这样.

这是代码:

def sum_to_n?(arr, n)
  arr.each {|x| arr.each {|y| return true if x + y == n && x != y}}
  return true if n == 0 && arr.length == 0
  return false
end
Run Code Online (Sandbox Code Playgroud)

用另一种方法,我得到了我想要的东西,只是几笔钱而不重复任何一个,甚至总结相同的数字,但它看起来很可怕,而且我很确定有人会因为这样做而杀了我,但是你可以看到这个方法做得很好:

arr[1, 2, 3, 4] => 1+2, 1+3, 1+4, 2+3, 2+4, 3+4
Run Code Online (Sandbox Code Playgroud)

这是代码:

def sum_to_n?(arr, n)
  for i in 0..arr.length - 1
    k = i + 1
    for k in k..arr.length - 1
      sum = arr[i] + arr[k]
      if sum == n
        return true
      end
    end
  end
  return true if n == 0 && arr.length == 0
  return false
end
Run Code Online (Sandbox Code Playgroud)

嗯,我希望你们在我尝试的时候做一个更好,更漂亮的方法.

谢谢您的帮助.

Jör*_*tag 20

我写的是这样的:

def sum_to_n?(arr, n)
  return true if arr.empty? && n.zero?
  arr.combination(2).any? {|a, b| a + b == n }
end
Run Code Online (Sandbox Code Playgroud)

这似乎是一个非常漂亮的Rubyish解决方案.

  • 你是个聪明人,我对此毫不怀疑.你能用这个问题的通用答案来启发我们吗?你的工作是因为一个方法可以实现OP所需要的,但是如果你有一个通用的嵌套循环呢?或者你不应该有,如果你做错了吗? (4认同)

roh*_*ulk 5

我在CodeWars上遇到过这个问题.该接受的答案肯定看起来非常Rubyish,但那是在性能为代价.调用arr.combination(2)结果有很多组合,按元素遍历数组并搜索"补码"是否sum - element存在更为简单.这是怎么样的 -

def sum_to_n?(arr, n)
  (arr.empty? and n.zero?) or arr.any? { |x| arr.include?(n - x) }
end
Run Code Online (Sandbox Code Playgroud)