我正在学习Ruby,接受伯克利的MOOC,而且在其中一些MOOC的作业中我们有一个练习:
定义方法sum_to_n?它采用一个整数数组和一个 附加整数n,作为参数,如果有的话,返回true 整数数组中的元素总和为n。一个空数组应该总和 根据定义为零。
我已经创建了两个可以完成这项工作的方法,但是我对它们中的任何一个都不满意,因为我认为它们不是用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
正如你所看到的,有很多重复的总和,我不希望这样。
这是代码:
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
通过我得到了我想要的,只是一个简单计算而无需重复任何人,甚至同样的数量相加的另一种方法,但它看起来太可怕了,我敢肯定有人会爱杀我做这个方式,但是你可以看到这个方法做得很好:
arr[1, 2, 3, 4] => 1+2, 1+3, 1+4, 2+3, 2+4, 3+4
这是代码:
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
好吧,我希望你们在尝试做一个更好,更漂亮的方法时玩得很开心。
感谢您的帮助。
答案 0 :(得分:19)
我会这样写:
def sum_to_n?(arr, n)
return true if arr.empty? && n.zero?
arr.combination(2).any? {|a, b| a + b == n }
end
这似乎是一个非常漂亮的Rubyish解决方案。
答案 1 :(得分:2)
除了@ jorg-w-mittag的回答。我找到了另一种使用“置换”的解决方案。
https://stackoverflow.com/a/19351660/66493
def sum_to_n?(arr, n)
(arr.empty? && n.zero?) || arr.permutation(2).any? { |a, b| a + b == n }
end
我以前不知道排列。 仍然喜欢@ jorg-w-mittag,因为它更具可读性。
答案 2 :(得分:1)
这个会在O(n.log(n))
而不是O(n²)
:
a = 1, 2, 3, 4
class Array
def sum_to? n
unless empty?
false.tap {
i, j, sorted = 0, size - 1, sort
loop do
break if i == j
a, b = sorted[i], sorted[j]
sum = a + b
return a, b if sum == n
sum < n ? i += 1 : j -= 1
end
}
end
end
end
a.sum_to? 7 #=> [3, 4]
答案 3 :(得分:0)
我曾经想过,对这个问题的任何答案的开头都应该从修剪数据的多余数据开始:
无法使用此功能:
arr.select! { |e| e <= n } # may be negative values
但这可能有所帮助:
arr.sort!
while arr[0] + arr[-1] > n # while smallest and largest value > n
arr.delete_at(-1) # delete largest vaue
end