生成Padovan序列

时间:2018-05-10 18:25:22

标签: python

Padovan序列由关系P(n + 1)= P(n-1)+ P(n-2)控制,因为n是a 非负整数,其中P(0)= P(1)= P(2)= 1.因此,例如,P(3)= 2,P(4)= 2,并且 P(5)= 3,依此类推。

我想编写一个Python程序Pad(n),它生成序列P(0),P(1),...,P(n - 1)。

这就是我目前所拥有的,但它只生成一个列表,其中第i个数字被复制到序列中的最大数字:

def ith(n):

    first, sec, third, fourth = 1, 1, 1, 1
    for i in range(3, n+1):
        fourth = first + sec
        first = sec
        sec = third
        third = fourth

    return fourth



def pad(n):
    pad = ith(n)
    lst = []
    for i in range(n):
        lst.append(pad)

    return lst

我希望它将它作为输出产生:

>>> Pad(6)
>>>[1,1,1,2,2,3]

目前我的代码只生成:

>>>[4,4,4,4,4,4]

我现在我将第i个值附加到列表中,但是我不知道如何将每个数字串联到最后一个数字的值。 Pad(6)产生4,因为这是之前的所有关系。

对不起我的错误描述和制定问题。

1 个答案:

答案 0 :(得分:1)

pad()函数中有两个小错误。

首先,你应该在循环中调用ith()函数(也不要将变量命名为pad,因为它的名称是功能,它可能会导致问题)。

其次,当你应该调用ith(n)时,你在循环内调用ith(i)。这就是你总是得到相同数字的原因 - ith()的参数在循环内没有改变。

pad()功能的固定版本为:

def pad(n):
    lst = []
    for i in range(n):
        val = ith(i)
        lst.append(val)

    return lst

您可以验证这确实为[1, 1, 1, 2, 2, 3]生成pad(6)的正确输出。

更有效的非递归方法

现在,虽然您的方法有效,但效率也非常低。您正在为ith()中的每个值调用range(n)函数,该函数从开始每个时间重新计算整个序列。

更好的方法是将中间结果存储在列表中,而不是通过调用函数来获取ith()值。

以下是更好方法的示例:

def pad2(n):
    lst = [1, 1, 1]  # initialize the list to the first three values in the sequence
    for i in range(3,n):
        lst.append(lst[i-2] + lst[i-3])  # use already computed values!
    # slice the list to only return first n values (to handle case of n <= 3)
    return lst[:n]

递归方法

Wikipedia所示,递归关系向我们显示pad(n) = pad(n-2) + pad(n-3)

使用此作为递归函数的起点:return pad(n-2) + pad(n-3)

这几乎是你需要的一切,除了我们必须定义序列的起始值。所以只要1返回n < 3,否则请使用递归关系:

def pad_recursive(n):
    if n < 3:
        return 1
    else:
        return pad_recursive(n-2) + pad_recursive(n-3)

然后,您可以通过列表理解获得序列中的第一个n值:

print([pad_recursive(n) for n in range(6)])
#[1, 1, 1, 2, 2, 3]

但是这会带来与原始函数相同的缺点,因为它会在每次迭代中从头开始计算整个序列。