简体   繁体   English

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

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

I'm new to Python. 我是Python的新手。 This is a homework problem, but it is tough as I only have a little experience in Java. 这是一个家庭作业问题,但它很难,因为我只有一点Java经验。 The code is supposed to print the first Catalan-numbers using its recursive definition: 该代码应该使用其递归定义打印第一个加泰罗尼亚数字:

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

EDIT: 编辑:

My current code looks like this, and the only remaining problem is to put all the C(n) numbers I get by this code in a txt using the savetxt() method. 我当前的代码看起来像这样,唯一剩下的问题是使用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]])

After this last problem is solved, I will try some other versions suggested in the answers (like filling up an array of zeroes first). 在最后一个问题解决之后,我将尝试在答案中建议的其他一些版本(比如先填充一个零数组)。

Index out of range. 指数超出范围。 Your first i is equal to 1 but c only has one element, which is index 0. So just change the range to (0,1000000000). 你的第一个i等于1,但c只有一个元素,即索引0.所以只需将范围改为(0,1000000000)。

By the way, don't use range, use xrange, it'll be faster and take less memory. 顺便说一句,不要使用范围,使用xrange,它会更快,占用更少的内存。 When you use range , Python creates an array of that size. 当您使用range ,Python会创建该大小的数组。 An array of size 1000000000 takes a ton of memory. 大小为1000000000的数组需要大量内存。 Instead, xrange create an iterator so it takes much less memory. 相反, xrange创建一个迭代器,因此它需要更少的内存。

You can get better use out of numpy by actually using an array (which also makes the code look more like I think you originally had it): 通过实际使用数组可以更好地利用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

If you can come up with a non-recursive definition, you can speed this up significantly (see eg Is a "for" loop necessary if elements of the a numpy vector are dependant upon the previous element? ). 如果你能提出一个非递归定义,你可以显着提高速度(参见例如,如果一个numpy向量的元素依赖于前一个元素,那么是否需要“for”循环? )。 Note that these numbers get big fast, though (you can only fit the first 34 in a 64-bit integer)! 请注意,这些数字变得很快(但是你只能在64位整数中使用前34个)!

This is almost an exact duplicate of Python:: "IndexError: list index out of range" ; 这几乎是Python ::“IndexError:list index超出范围”的完全重复; in there I proposed that instead of using the recurrence, one should just use the iterative formula to produce the Catalan numbers; 在那里我提出,不应该使用重复,而应该使用迭代公式来产生加泰罗尼亚数字; in your case you are using the iterative approach, but are storing them to an array. 在您的情况下,您正在使用迭代方法,但将它们存储到数组中。 My approach is quite memory efficient compared to creating an array to store all n Catalan numbers: 与创建存储所有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
for i in range(0, 1000000000):

This should work. 这应该工作。

On your first iteration, you are trying to use c[1], but it doesn't exist. 在第一次迭代中,您尝试使用c [1],但它不存在。 You only have a value for c[0], so the list index is out of range. 您只有c [0]的值,因此列表索引超出范围。

Wouldn't be easy if you use 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM