给出两个数字,比如说(14,18),问题是找到这个范围内所有数字的总和,递归地为14,15,16,17,18。现在,我已经使用循环完成了这项工作,但我无法递归地执行此操作。
这是我的递归解决方案:
def sum_cumulative_recursive(a,b)
total = 0
#base case is a == b, the stopping condition
if a - b == 0
puts "sum is: "
return total + a
end
if b - a == 0
puts "sum is: "
return total + b
end
#case 1: a > b, start from b, and increment recursively
if a > b
until b > a
puts "case 1"
total = b + sum_cumulative_recursive(a, b+1)
return total
end
end
#case 2: a < b, start from a, and increment recursively
if a < b
until a > b
puts "case 2"
total = a + sum_cumulative_recursive(a+1, b)
return total
end
end
end
以下是一些示例测试用例:
puts first.sum_cumulative_recursive(4, 2)
puts first.sum_cumulative_recursive(14, 18)
puts first.sum_cumulative_recursive(-2,-2)
我的解决方案适用于&gt; b,和&lt; b,但它不适用于== b。
如何修复此代码以使其有效?
感谢您的时间。
答案 0 :(得分:0)
我这样做:
def sum_cumulative_recursive(a, b)
a, b = a.to_i, b.to_i # Only works with ints
return sum_cumulative_recursive(b, a) if a > b
return a if a == b
return a + sum_cumulative_recursive(a+1, b)
end
答案 1 :(得分:0)
这是一种做法。我认为这只是一个练习,因为范围r
的元素之和当然只是(r.first+r.last)*(f.last-r.first+1)/2
。
def sum_range(range)
return nil if range.last < range.first
case range.size
when 1 then range.first
when 2 then range.first + range.last
else
range.first + range.last + sum_range(range.first+1..range.last-1)
end
end
sum_range(14..18) #=> 80
sum_range(14..14) #=> 14
sum_range(14..140) #=> 9779
sum_range(14..139) #=> 9639
答案 2 :(得分:0)
def sum_cumulative_recursive(a,b)
return a if a == b
a, b = [a,b].sort
a + sum_cumulative_recursive(a + 1, b)
end
修改强>
这是我从一些非正式基准中可以看到的最有效的解决方案:
def sum_cumulative_recursive(a,b)
return a if a == b
a, b = b, a if a > b
a + sum_cumulative_recursive(a + 1, b)
end
使用:
Benchmark.measure { sum_cumulative_recursive(14,139) }
我的初步回复基准:0.005733
@ Ajedi32的回应基准:0.000371
我的新回复的基准:0.000115
我也惊讶地发现,在某些情况下,递归解决方案接近或超过了更自然的inject
解决方案的效率:
Benchmark.measure { 10.times { (1000..5000).inject(:+) } }
# => 0.010000 0.000000 0.010000 ( 0.027827)
Benchmark.measure { 10.times { sum_cumulative_recursive(1000,5000) } }
# => 0.010000 0.010000 0.020000 ( 0.019441)
如果你把它放得太远,你会遇到stack level too deep
错误......
答案 3 :(得分:0)
另一种解决方案是使用前端调用来修复无序参数,然后使用私有递归后端来完成实际工作。我发现,一旦你确定它们是干净的,就可以避免重复检查参数。
def sum_cumulative_recursive(a, b)
a, b = b, a if b < a
_worker_bee_(a, b)
end
private
def _worker_bee_(a, b)
a < b ? (a + _worker_bee_(a+1,b-1) + b) : a == b ? a : 0
end
这个变体会通过从两端求和来将堆栈需求减少一半。
如果你不喜欢这种方法和/或你真的想要削减堆栈大小:
def sum_cumulative_recursive(a, b)
if a < b
mid = (a + b) / 2
sum_cumulative_recursive(a, mid) + sum_cumulative_recursive(mid+1, b)
elsif a == b
a
else
sum_cumulative_recursive(b, a)
end
end
这应该将堆栈大小保持为O(log | b-a |)。