我试图找到数字x的最大素数因子,Python给出了范围太大的错误。我尝试过使用x range但是我遇到了OverflowError:Python int太大而无法转换为C long
x = 600851475143
maxPrime = 0
for i in range(x):
isItPrime = True
if (x%i == 0):
for prime in range(2,i-1):
if (i%prime == 0):
isItPrime = False
if (isItPrime == True):
if (i > maxPrime):
maxPrime = i;
print maxPrime
答案 0 :(得分:28)
在旧的(2.x)版本的Python中,xrange
只能处理Python 2.x int
,它们受本机长整数大小的约束你的平台。另外,range
预先在Python 2.x上分配一个包含所有数字的列表,因此不适用于大型参数。
您可以切换到3.x(推荐),或者long int
(在C中)为64位长的平台,或者使用以下插件:
import itertools
range = lambda stop: iter(itertools.count().next, stop)
同样地,以简单的形式:
def range(stop):
i = 0
while i < stop:
yield i
i += 1
答案 1 :(得分:6)
这就是我要做的事情:
def prime_factors(x):
factors = []
while x % 2 == 0:
factors.append(2)
x /= 2
i = 3
while i * i <= x:
while x % i == 0:
x /= i
factors.append(i)
i += 2
if x > 1:
factors.append(x)
return factors
>>> prime_factors(600851475143)
[71, 839, 1471, 6857]
这很快,我认为是对的。采用所发现因素的最大值非常简单。
2017年11月8日
回到这5年之后,我会使用yield
和yield from
以及在主要范围内更快地计算:
def prime_factors(x):
def diver(x, i):
j = 0
while x % i == 0:
x //= i
j += 1
return x, [i] * j
for i in [2, 3]:
x, vals = diver(x, i)
yield from vals
i = 5
d = {5: 2, 1: 4}
while i * i <= x:
x, vals = diver(x, i)
yield from vals
i += d[i % 6]
if x > 1:
yield x
list(prime_factors(600851475143))
dict {5: 2, 1: 4}
使用的事实是你不必查看所有奇数。高于3,所有数字x % 6 == 3
都是3的倍数,因此您只需要查看x % 6 == 1
和x % 6 == 5
,您可以通过交替添加2和4来跳转到这些数字,从5开始
答案 2 :(得分:4)
接受的答案表明xrange的替代品,但仅涵盖一个案例。这是一个更普遍的替代品。
def custom_range(start=0,stop=None,step=1):
'''xrange in python 2.7 fails on numbers larger than C longs.
we write a custom version'''
if stop is None:
#handle single argument case. ugly...
stop = start
start = 0
i = start
while i < stop:
yield i
i += step
xrange=custom_range
答案 3 :(得分:1)
我肯定会坚持使用xrange,因为创建一个介于0之间的列表,看起来像无穷大的数字会对内存造成负担。 xrange只会在被问到时生成数字。对于数量太大的问题,您可能想尝试“长”。这可以通过在数字的末尾写一个L来实现。我制作了自己的版本来测试它。我进行了一次小睡眠,以免将我的计算机破坏成几乎while(1)
的循环。我也不耐烦地看到程序完全结束,所以我输入了打印语句
from time import sleep
x = 600851475143L
maxPrime = 0
for i in xrange(1,x):
isItPrime = True
if (x%i) == 0:
for prime in xrange(2,i-1):
if (i%prime) == 0:
isItPrime = False
break
if isItPrime:
maxPrime = i
print "Found a prime: "+str(i)
sleep(0.0000001)
print maxPrime
希望这有帮助!
编辑: 我还做了一些编辑以产生这个版本。这是相当有效的,我检查了这个程序提供的相当多的数字(它似乎到目前为止检查):
from time import sleep
x = 600851475143L
primes = []
for i in xrange(2,x):
isItPrime = True
for prime in primes:
if (i%prime) == 0:
isItPrime = False
break
if isItPrime:
primes.append(i)
print "Found a prime: "+str(i)
sleep(0.0000001)
print primes[-1]
答案 4 :(得分:0)
非常有用的代码,这不是获取分隔符的最佳方式,我已经使用for
和range
完成了它,但我无法执行它由于变量很长,所以我决定用一段时间来实现它,并自己增加一个计数器。
对于32位int
,如13195:
# The prime factors of 13195 are 5, 7, 13 and 29.
# What is the largest prime factor of the number 600851475143 ?
i = 13195
for j in xrange(2, i, 1):
if i%j == 0:
i = i/j
print j
更长的数字的好方法:
# The prime factors of 13195 are 5, 7, 13 and 29.
# What is the largest prime factor of the number 600851475143 ?
i = 600851475143
j = 2
while i >= j:
if i%j == 0:
i = i/j
print j
j = j+1
最后一个素数是最后一个打印值。
答案 5 :(得分:0)
python 2 range()
的另一种实现方式:
import itertools
import operator
def range(*args):
"""Replace range() builtin with an iterator version."""
if len(args) == 0:
raise TypeError('range() expected 1 arguments, got 0')
start, stop, step = 0, args[0], 1
if len(args) == 2: start, stop = args
if len(args) == 3: start, stop, step = args
if step == 0:
raise ValueError('range() arg 3 must not be zero')
iters = itertools.count(start, step)
pred = operator.__ge__ if step > 0 else operator.__le__
for n in iters:
if pred(n, stop): break
yield n