我被Ruby解决了这个问题:
计算给定范围a到b的立方体总和。编写一个名为sum_of_cubes的方法来完成此任务。
我写了这个:
def sum_of_cubes(a, b)
sum = 0
for x in a..b
c = x ** 3
end
sum += c
end
我得到了b的立方体的值。这段代码有什么问题?如何通过简单的循环解决这个问题?
谢谢!
答案 0 :(得分:8)
def sum_of_cubes min, max
(min..max).reduce(0) { |a, b| a + b ** 3 }
end
对这里发生的事情的一点解释
我们从范围(min..max)
开始,这是一个Enumerable
irb> (1..3).is_a? Enumerable
=> true
使用我们从reduce
获得的Enumerable
实例方法,我们可以使用为我们(可枚举)范围中的每个项调用的代码块,并最终返回单个值。
如果您认为"将我的项目组和将减少为单个值,则函数名称是有意义的。"
这是我们的块
{ |a, b| a + b ** 3 }
我们使用reduce
调用0
,这是a
param
在后续调用中,块的返回值将传递给块的a
参数
范围内的每件商品都会传递到商品b
param
让我们一步一步看看它是如何运作的
(1..3).reduce(0) { |a, b| a + b ** 3 }
第一次阻止调用获得a=0
(初始值)和b=1
(我们范围内的第一项)
我们块的返回值为0 + 1 ** 3
或1
第二次阻止调用获得a=1
(上次通话的返回值)和b=2
(我们范围内的第二项)
我们块的返回值为1 + 2 ** 3
或9
第三次阻止调用获得a=9
(上一次调用的返回值)和b=3
(我们范围内的第三项和最后一项)
我们块的返回值为9 + 3 ** 3
或36
reduce
的最终返回值是最后一次调用的块的返回值
在这种情况下36
答案 1 :(得分:3)
您需要在循环内部sum += c
。完成后返回sum
。
答案 2 :(得分:3)
这是另一种计算方法。它没有解决你的循环问题,但我认为值得一提。
整数13 + 23 + 33 + ... + n3
的立方体总和由公式(n(n + 1)/2)2
给出,因此给定范围 min..max
的多维数据集总和由下式给出: :
(max(max + 1)/2)2 - ((min-1)((min-1) + 1)/2)2
在代码中,这可能看起来像:
def sum_of_cubes_fixed min, max
lower = min - 1
(((max * (max + 1))/2) ** 2) - (((lower * (lower + 1))/2) ** 2)
end
这段代码避免了循环,因此O(1)而不是O(n)(差不多 - 我在这里挥手一点,乘法和取幂的时间复杂度将取决于数字的大小)。对于小尺寸范围,您不会注意到这一点,但对于较大尺寸,这与环形版本之间的差异变得越来越明显。我没有做过任何严格的基准测试,但使用reduce
方法在1到10,000,000范围内对我的机器进行快速测试需要几秒钟,但这种方法几乎是即时的。
通常我只会使用reduce
这样的东西,但任务的结构表明可能有更好的方法。在谷歌的帮助下,我找到了这个公式并提出了一个更有效的解决方案(至少对于大范围)。
答案 3 :(得分:3)
(a..b).map{|i| i**3 }.inject(&:+)
map and inject完美地完成了工作。
编辑:虽然它遍历列表两次;)