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

关于加泰罗尼亚数字的Python代码有什么问题?,python,numpy,catalan,Python,Numpy,Catalan,我是Python新手。这是一个家庭作业问题,但很难,因为我在Java方面只有一点经验。代码应该使用其递归定义打印第一个加泰罗尼亚数字: C(n + 1) = C(n) * (4n + 2) / (n + 2) 编辑: 我当前的代码看起来是这样的,剩下的唯一问题是使用savetxt()方法将通过该代码获得的所有C(n)数字放入一个txt中 最后一个问题解决后,我将尝试答案中建议的其他版本(如先填充一个零数组)。索引超出范围。第一个i等于1,但c只有一个元素,即索引0。所以只需将范围更改为(010

我是Python新手。这是一个家庭作业问题,但很难,因为我在Java方面只有一点经验。代码应该使用其递归定义打印第一个加泰罗尼亚数字:

C(n + 1) = C(n) * (4n + 2) / (n + 2)
编辑:

我当前的代码看起来是这样的,剩下的唯一问题是使用savetxt()方法将通过该代码获得的所有C(n)数字放入一个txt中


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

索引超出范围。第一个
i
等于1,但
c
只有一个元素,即索引0。所以只需将范围更改为(01000000000)

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

for i in range(0, 1000000000):
这应该行得通

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

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


如果你能想出一个非递归的定义,你可以大大加快这一速度(参见例)。但是请注意,这些数字很快就会变大(您只能在64位整数中拟合前34位)

这几乎是一个精确的复制品;在那里,我建议,不使用递归,而应该使用迭代公式来产生加泰罗尼亚数;在您的例子中,您使用的是迭代方法,但将它们存储到一个数组中。与创建一个数组来存储所有
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

如果你在一段时间内使用,那就不容易了

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

虽然您不需要if语句来中断此处的循环,但您仅使用
numpy
导出数据,这似乎效率不高!如果您事先创建了一个空数组(例如使用
numpy.zero
),则可以对所有数组进行索引。很抱歉,我忘记添加问题:查找并列出小于1.000.000.000的所有C(n)的n和C(n)。for循环中的范围表示最后一个C(n)数不是第十亿个C(n)。我可以优化for循环的范围(或者使用while,但是我们还没有在课程中使用它,所以我必须弄清楚)。我将尝试使用空数组,jonrsharpe,谢谢!它似乎可以工作(内存错误与范围,但没有错误与xrange)。我现在正在搜索文件输出,我将编辑此评论并接受您的答案(不幸的是,我不允许将您的答案标记为有用,但这是一个非常有用的简短答案,对此我非常感谢!)。编辑:不幸的是,文件只有这一行:“1.90000000000e+01 1.767263190000000000e+09”。是的,还要注意,在for循环之外,
i
取最后一个值,所以您只需将最后一个值附加到numpyth。这是我的下一个问题:如何实现在savetxt()方法中写入for stlye循环?我记得类似于[0:x]的东西。是的,虽然这会给出从0到x-1的所有c值,因为它不包括最后一个值。我认为你可以通过这样做完全摆脱循环,例如
a=np.arange(15)
((4*a)+2)/(a+2)).cumprod()
(然后你可能想要将其转换为整数数组)。但是,正如你所说,数字很快就会变大,可能会溢出!我很感激你的回答,我真的觉得它更熟悉。如果我没有弄错的话,我只需要用一个np.savetxt(“…”,np.c_I[I,catalan[I]])来结束。它是正确的吗?@ajcr那不是完全相同的系列(
1,2,4,8,24
vs
1,1,2,5,14
)@MitlasóczkiBence你为什么不试试看呢?你确定它产生了其他系列吗
((4*a)+2)/(a+2)).cumprod()
生成了一个数组,其中包含
1,2,5,14,42,132,429,
——当我运行它时,
n=1,2,3,4,
的加泰罗尼亚数字。谢谢你清理它!但是,代码还有更多的问题(请参阅我对其他答案的其他评论)。很可能这个问题在大学编程课程中很常见。然而,写(复制)一段我不懂的代码是没有用的:我的目标是既完成家庭作业,又熟悉我在课程中看到的方法。在您编写的代码中,我不知道yield、itertools和list,它们不应该用于解决问题。不过,谢谢你的回答!
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
C1,C2 = 1.0, 1.0
n=0
while C1<=1000000000:
    print(C1)
    C1,C2 = (((4*n+2)/(n+2)) * (C1)), C1
    n+=1