关于加泰罗尼亚数字的 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
我是 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