关于加泰罗尼亚数字的 Python 代码有什么问题?

What is wrong with this Python code about the Catalan numbers?

我是 Python 的新手。这是一道作业题,但我对Java只有一点点经验,所以很难。该代码应该使用其递归定义打印第一个加泰罗尼亚数字:

C(n + 1) = C(n) * (4n + 2) / (n + 2)

编辑:

我目前的代码是这样的,唯一剩下的问题是使用 savetxt() 方法将我通过这段代码得到的所有 C(n) 数放入一个 txt 文件中。

import numpy

c = []
c.append(1)
for i in xrange(0,1000000000):
    c.append((4*i+2)*c[i]/(i+2))
    print (c[i])
    if c[i]>= 1000000000:
        break


numpy.savetxt("catalan",numpy.c_[i, c[i]])

在最后一个问题解决后,我将尝试答案中建议的其他一些版本(例如先填充一个零数组)。

索引超出范围。您的第一个 i 等于 1,但 c 只有一个元素,即索引 0。因此只需将范围更改为 (0,1000000000)。

顺便说一下,不要使用range,使用xrange,它会更快并且占用更少的内存。当您使用 range 时,Python 会创建一个该大小的数组。大小为 1000000000 的数组需要大量内存。相反,xrange 创建一个迭代器,这样它占用的内存就少得多。

for i in range(0, 1000000000):

这应该有效。

在您的第一次迭代中,您尝试使用 c[1],但它不存在。 您只有 c[0] 的值,因此列表索引超出范围。

您可以通过实际使用数组来更好地利用 numpy(这也使代码看起来更像我认为您最初拥有的代码):

import numpy as np

def catalan(x):
    """Create an array of the first x 'Catalan numbers'."""
    c = np.zeros(x)
    c[0] = 1
    for n in xrange(x-1):
        c[n+1] = c[n] * ((4 * n) + 2) / (n + 2)
    return c

如果你能想出一个非递归定义,你可以显着加快速度(参见 Is a "for" loop necessary if elements of the a numpy vector are dependant upon the previous element?)。不过请注意,这些数字变大的速度很快(您只能将前 34 位放入 64 位整数中)!

这几乎是 的完全重复;在那里我建议不要使用递归,而应该只使用迭代公式来产生加泰罗尼亚数;在您的情况下,您使用的是迭代方法,但将它们存储到一个数组中。与创建一个数组来存储所有 n 加泰罗尼亚语数字相比,我的方法是非常有效的内存:

def catalans():
    C = 1
    n = 0
    while True:
        yield C
        C = 2 * (2 * n + 1) * C // (n + 2)
        n += 1

with open('catalan', 'w') as output:
    for n, C in enumerate(1, catalans()):
        print(n, C, file=output)
        if C >= 1000000000:
            break

用while岂不是很简单?

C1,C2 = 1.0, 1.0
n=0
while C1<=1000000000:
    print(C1)
    C1,C2 = (((4*n+2)/(n+2)) * (C1)), C1
    n+=1