我正在使用基本的Python MIT免费课件,我遇到了一个带有递归练习的墙。原始程序采用整数并使用递归提供其Fibonacci。本书提供了该程序的脚本,但随后的练习要求为程序输入一种方法,以便识别fib(2)
在计算fib(n)
的过程中执行的次数。我希望得到一些帮助,因为我已经坚持了一个星期了。
以下是代码:
def fib(n):
"""Assumes n is int > 0
Returns Fibonacci Number of n"""
if n ==0 or n==1:
return n
else:
return fib(n-1) + fib(n-2)
def testfib(n):
for i in range(n+1):
print('fib of', i, 'is ', fib(i))
x=int(input('Enter a number: '))
print('Fibonacci of', x, 'is',fib(x))
print(testfib(x))
参考:使用Python计算和编程简介,图4.7
答案 0 :(得分:3)
在函数本身内包含计数器,让它返回两个值(斐波那契值和计数)。这使您无需手动执行重置计数的业务逻辑。您可以根据需要多次调用该函数,并且计数将是正确的,而不是每次曾调用fib
时的总计数。
def fib(n):
"""Assumes n is int > 0
Returns the nth Fibonacci number and number of times it was called"""
if n == 0 or n == 1:
return n, 0
else:
f1, count1 = fib(n-1)
f2, count2 = fib(n-2)
sum_counts = count1 + count2
if n == 2:
sum_counts = 1
return f1 + f2, sum_counts
def testfib(n):
for i in range(n+1):
f, count = fib(i)
print('fib of', i, 'is ', f, end="\t")
print('count of fib(2) is ', count)
x = int(input('Enter a number: '))
print('Fibonacci of', x, 'is', fib(x)[0])
print(testfib(x))
输出结果为:
Enter a number: 7
Fibonacci of 7 is 13
fib of 0 is 0 count of fib(2) is 0
fib of 1 is 1 count of fib(2) is 0
fib of 2 is 1 count of fib(2) is 1
fib of 3 is 2 count of fib(2) is 1
fib of 4 is 3 count of fib(2) is 2
fib of 5 is 5 count of fib(2) is 3
fib of 6 is 8 count of fib(2) is 5
fib of 7 is 13 count of fib(2) is 8
None
由于问题以不同的方式处理n == 2
情况,您可以在递归中使另一个基本情况。
def fib(n):
"""Assumes n is int > 0
Returns Fibonacci Number of n and number fo times it was called"""
if n == 0 or n == 1:
return n, 0
elif n == 2:
return (fib(0) + fib(1)), 1
else:
f1, count1 = fib(n-1)
f2, count2 = fib(n-2)
return f1 + f2, count1 + count2
答案 1 :(得分:1)
这利用了由PEP 232建立的Python鲜为人知的特性,以避免全局变量或创建完整的类。 Python函数可以有自己的属性,可以用来提供与其他语言中的静态变量相同的功能。因此,在您的代码中,您可以执行以下操作:
def fib(n):
"""Assumes n is int > 0
Returns Fibonacci Number of n"""
if n == 2:
try:
fib.two_count += 1
except AttributeError:
fib.two_count = 1
if n ==0 or n==1:
return n
else:
return fib(n-1) + fib(n-2)
def testfib(n):
for i in range(n+1):
fib.two_count = 0
print(
'fib of', i, 'is ', fib(i),
'and fib(2) was called', fib.two_count, 'times'
)
x=int(input('Enter a number: '))
print('Fibonacci of', x, 'is',fib(x))
print(testfib(x))
答案 2 :(得分:0)
可能有点矫枉过正,但将整个事情包装成一个类,你可以轻松地引入一个计数器。在这里,您首先创建一个名为fib的可调用fib(x)
对象。当您现在调用__call__
时,Fib.fib
函数中的计数器设置为零,然后调用执行实际工作的Fib.fib
函数。在class Fib:
def __init__(self):
self.count = 0
def __call__(self, n):
self.count = 0
return self.fib(n)
def fib(self,n):
"""Assumes n is int > 0
Returns Fibonacci Number of n"""
if n == 2:
self.count += 1
if n ==0 or n==1:
return n
else:
return self.fib(n-1) + self.fib(n-2)
fib = Fib()
x=5
print('Fibonacci of', x, 'is',fib(x))
print('fib(2) was called {} times'.format(fib.count))
函数内,每当函数参数等于2时,计数器就会增加1。
x=5
对于示例参数(Fibonacci of 5 is 5
fib(2) was called 3 times
),输出为:
var editor = new $.fn.dataTable.Editor({
ajax: '@Url.Action("ProductOutputList")',
table: '#productoutputs',
fields: [
{
"label": "Name:",
"name": "productoutputs.Name"
}], //more fields
formOptions: {
inline: {
onBlur: 'submit'
}
}
});
// Activate an inline edit on click of a table cell
$('#productoutputs').on('click', 'tbody td.editable', function (e) {
editor.inline(this);
});
答案 3 :(得分:0)
有更简洁的方法可以做到这一点,但简单的方法是使用一个全局变量来计算何时使用arg为2调用fib
的计数。你需要记住在每个最外层之前重置计数器但是打电话。
count = 0
def fib(n):
"""Assumes n is int > 0
Returns Fibonacci Number of n"""
global count
if n == 0 or n == 1:
return n
else:
if n == 2:
count += 1
return fib(n-1) + fib(n-2)
def testfib(n):
global count
for i in range(n+1):
count = 0
print('fib of', i, 'is ', fib(i), ', called fib(2)', count, 'times')
x=int(input('Enter a number: '))
count = 0
print('Fibonacci of', x, 'is', fib(x), ', called fib(2)', count, 'times')
testfib(x)
<强>演示强>
Enter a number: 7
Fibonacci of 7 is 13 , called fib(2) 8 times
fib of 0 is 0 , called fib(2) 0 times
fib of 1 is 1 , called fib(2) 0 times
fib of 2 is 1 , called fib(2) 1 times
fib of 3 is 2 , called fib(2) 1 times
fib of 4 is 3 , called fib(2) 2 times
fib of 5 is 5 , called fib(2) 3 times
fib of 6 is 8 , called fib(2) 5 times
fib of 7 is 13 , called fib(2) 8 times
稍微好一点的方法是使用函数属性而不是可修改的全局属性。
def fib(n):
"""Assumes n is int > 0
Returns Fibonacci Number of n"""
if n == 0 or n == 1:
return n
else:
if n == 2:
fib.count += 1
return fib(n-1) + fib(n-2)
def testfib(n):
for i in range(n+1):
fib.count = 0
print('fib of', i, 'is ', fib(i), ', called fib(2)', fib.count, 'times')
x=int(input('Enter a number: '))
fib.count = 0
print('Fibonacci of', x, 'is', fib(x), ', called fib(2)', fib.count, 'times')
testfib(x)
答案 4 :(得分:0)
你可以通过向函数添加一个可变参数来计算实际的Fibonacci数 - 它每次被调用时都会递增 - 并隐藏现在有一个带有包装函数的额外参数的事实:
这就是我的意思:
def dofib(n, count):
"""Assumes n is int >= 0
Returns Fibonacci Number of n."""
count[0] += 1
if n==0 or n==1:
return n
else:
return dofib(n-1, count) + dofib(n-2, count)
def fib(n):
"""Assumes n is int >= 0
Returns Fibonacci Number of n and number of recursive calls."""
count = [0]
return dofib(n, count), count[0]
def testfib(n):
for i in range(n+1):
print('fib of {0} is {1[0]} (call count: {1[1]})'.format(i, fib(i)))
x=int(input('Enter a number: '))
print('Fibonacci of {0} is {1[0]} (call count: {1[1]})'.format(x, fib(x)))
testfib(x)
示例输出:
Fibonacci of 7 is 13 (call count: 41)
fib of 0 is 0 (call count: 1)
fib of 1 is 1 (call count: 1)
fib of 2 is 1 (call count: 3)
fib of 3 is 2 (call count: 5)
fib of 4 is 3 (call count: 9)
fib of 5 is 5 (call count: 15)
fib of 6 is 8 (call count: 25)
fib of 7 is 13 (call count: 41)