我有一种方法来计算输入数的阶乘
def fact( n )
if (n == 0)
1
else
n * fact(n-1)
end
end
我想创建一个循环来测试此方法的最大可计算值。对于我的机器,这个数字是8734,但我发现通过反复试验。
我的想法是创建一个for / each循环并测试返回的结果是否是实数。我只想放置实际产生实际数值结果的最后一个数值。
谢谢!
答案 0 :(得分:1)
我会做这样的事情:
i = 1
loop do
begin
fact(i)
rescue SystemStackError
puts "stack level too deep at: #{i}"
break
end
i += 1
end
请注意,这是一个非常天真的算法,可以检查每个数字,可能需要一些时间。在一系列数字上进行某种二元搜索必须更快。
答案 1 :(得分:0)
你可以像@spickermann所建议的那样,但是没有必要搜索引发异常的fact
的参数。相反,只需为任何适当大的fact(n)
值(例如n
)计算n = 100_000
,每次调用fact
时递增堆栈深度计数器,并报告其值提出SystemStackError
异常时的计数器。以下代码对n
的各种值执行该计算,表明n
的值不重要,只要它适当大。我认为n = 100_000
对于任何Ruby实现来说都是很大的,但是如果你愿意,可以把它变成一百万。
def fact( n )
@stack_size += 1
if (n == 0)
1
else
n * fact(n-1)
end
end
[10_000, 20_000, 50_000, 100_000, 8733, 8732].each do |n|
print "n=#{n.to_s.ljust(6)}: "
begin
@stack_size = 0
fact(n)
rescue SystemStackError
puts "stack level too deep at: #{@stack_size}"
end
end
# n=10000 : stack level too deep at: 8733
# n=20000 : stack level too deep at: 8733
# n=50000 : stack level too deep at: 8733
# n=100000: stack level too deep at: 8733
# n=8733 : stack level too deep at: 8733
# n=8732 :
请注意,n => 8732
时未引发异常。
最大堆栈深度是否取决于方法?当然!如果我们将fact
替换为:
def fact(n)
@stack_size += 1
fact(n-1)
end
我们得到:
# stack level too deep at: 9356