无法为递归Fibonacci程序添加功能

时间:2017-06-02 16:00:52

标签: python recursion fibonacci

我正在使用基本的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

5 个答案:

答案 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)