Python 素因子分解:不';你不能和大数字打交道吗?
我想找出一个数的最大素因子。当与较小的数字一起使用时,代码在空闲状态下正确运行,但当我将较大的数字(如600851475143)分配给n时,代码似乎根本不会在屏幕上打印任何内容。为什么?Python 素因子分解:不';你不能和大数字打交道吗?,python,Python,我想找出一个数的最大素因子。当与较小的数字一起使用时,代码在空闲状态下正确运行,但当我将较大的数字(如600851475143)分配给n时,代码似乎根本不会在屏幕上打印任何内容。为什么? def isPrime(n): isPrime = True for i in range(2,n-1): if n % i == 0: isPrime = False return isPrime largest = 0 n = 60
def isPrime(n):
isPrime = True
for i in range(2,n-1):
if n % i == 0:
isPrime = False
return isPrime
largest = 0
n = 600851475143
for i in range(2,n-1):
if isPrime(i) and n % i == 0:
largest = i
n = n / i
continue
print("The largest prime factor is", largest)
顺便说一下,我正在运行Python 3.3
==============================================================================
谢谢大家
我修改了我的原始代码如下:
def isPrime(n):
for i in range(2,n-1):
if n % i == 0:
return False
return True
largest = 0
n = 600851475143
for i in range(2,n-1):
if isPrime(i) and n % i == 0:
largest = i
if i == n:
break
n = n / i
print("The largest prime factor is", largest)
正如Nakedfanic所说,他们的代码运行得更快,我对其进行了轻微的编辑:
largest = 0
n = 600851475143
i = 2
while True:
if n % i == 0:
largest = i
if n == i:
# finished
break
n = n / i
else:
i += 1
print("The largest prime factor is", largest)
最有可能的是,您的代码没有以大的
n
终止,这仅仅是因为循环运行的时间太长。最有可能的是,您的代码没有以大的n
终止,这仅仅是因为循环运行的时间太长
isPrime = True
for i in range(2,n-1):
if n % i == 0:
isPrime = False
return isPrime
由于无条件的返回
,此循环始终退出第一次迭代。尝试:
for i in range(2,n-1):
if n % i == 0:
return False
return True
此外,上限n-1
可以减少为sqrt(n)+1
由于无条件的返回
,此循环始终退出第一次迭代。尝试:
for i in range(2,n-1):
if n % i == 0:
return False
return True
此外,上限
n-1
可以减少到sqrt(n)+1
有几个优化方面:
- 所有因子分解只需达到
(含)sqrt(n)
- 将
转换为表查找 使用isPrime()
初始化查找表,然后只计算一次所有素数n
,并循环遍历它们。
正如评论所指出的,这会占用大量内存空间。我们可以使用bit flag将内存需求减少到1/8,如果我们跳过所有偶数,我们可以将内存需求再减少一半(然后必须分别测试n是否为偶数)。但对于大型
,这可能仍然令人望而生畏n
- (如果使用当前代码)在
中提前返回(由@justhalf编写)isPrime()
- 查找最大因子时向后循环(从
到2)sqrt(n)
- 如果商除以因子(除以@justhalf)后为1,则提前返回
- 这篇文章(由@prashant建议)包含了更复杂的算法(使我的建议非常幼稚)>有几个优化方面:
- 所有因子分解只需达到
(含)sqrt(n)
- 将
转换为表查找 使用isPrime()
初始化查找表,然后只计算一次所有素数n
,并循环遍历它们。
正如评论所指出的,这会占用大量内存空间。我们可以使用bit flag将内存需求减少到1/8,如果我们跳过所有偶数,我们可以将其再减少一半(然后必须分别测试n是否为偶数)。但对于大的
,这可能仍然令人望而生畏n
- (如果使用当前代码)在
中提前返回(由@justhalf编写)isPrime()
- 查找最大因子时向后循环(从
到2)sqrt(n)
- 如果商除以因子(除以@justhalf)后为1,则提前返回
- 这篇文章(由@prashant建议)包含了更复杂的算法(使我的建议非常幼稚)这是因为即使
已经是1,你仍在不断尝试 此代码将帮助您查看问题:n
这将产生: ... Checking whether 6857 divides 6857 Checking whether 6858 divides 1 Checking whether 6859 divides 1 Checking whether 6860 divides 1 Checking whether 6861 divides 1 Checking whether 6862 divides 1 Checking whether 6863 divides 1 Checking whether 6864 divides 1 Checking whether 6865 divides 1 Checking whether 6866 divides 1 Checking whether 6867 divides 1 Checking whether 6868 divides 1 Checking whether 6869 divides 1 Checking whether 6870 divides 1 Checking whether 6871 divides 1 Checking whether 6872 divides 1 Checking whether 6873 divides 1 ...def isPrime(n): for i in xrange(2,n-1): if n % i == 0: return False return True largest = 0 n = 600851475143 for i in xrange(2,n-1): print 'Checking whether %d divides %d' % (i,n) if isPrime(i) and n % i == 0: largest = i n = n / i continue print("The largest prime factor is", largest)
无论如何,你的代码可能会有很大的改进,哈哈,看看其他人的建议。这是因为你一直在尝试,即使
已经是1 此代码将帮助您查看问题:n
这将产生: ... Checking whether 6857 divides 6857 Checking whether 6858 divides 1 Checking whether 6859 divides 1 Checking whether 6860 divides 1 Checking whether 6861 divides 1 Checking whether 6862 divides 1 Checking whether 6863 divides 1 Checking whether 6864 divides 1 Checking whether 6865 divides 1 Checking whether 6866 divides 1 Checking whether 6867 divides 1 Checking whether 6868 divides 1 Checking whether 6869 divides 1 Checking whether 6870 divides 1 Checking whether 6871 divides 1 Checking whether 6872 divides 1 Checking whether 6873 divides 1 ... 无论如何,您的代码可能会有很大的改进,哈哈,请参考其他人的建议。您的代码运行时间为O(n²),这意味着随着n的增加,它将很快变得异常缓慢。这就是为什么您的算法适用于小值,但适用于大值 这段代码在O(n)时间内做同样的事情,根本不做任何素数检查,并立即返回一个结果:def isPrime(n): for i in xrange(2,n-1): if n % i == 0: return False return True largest = 0 n = 600851475143 for i in xrange(2,n-1): print 'Checking whether %d divides %d' % (i,n) if isPrime(i) and n % i == 0: largest = i n = n / i continue print("The largest prime factor is", largest)
您的代码运行时间为O(n²),这意味着随着n的大小的增加,它将很快变得异常缓慢。这就是为什么您的算法适用于小值,但适用于大值 这段代码在O(n)时间内做同样的事情,根本不做任何素数检查,并立即返回一个结果:prime_factors = [] n = 600851475143 i = 2 while True: if n % i == 0: prime_factors.append(i) if n == i: # finished break n = n / i else: i += 1 print("The largest prime factor is", prime_factors[-1])
prime_factors = [] n = 600851475143 i = 2 while True: if n % i == 0: prime_factors.append(i) if n == i: # finished break n = n / i else: i += 1 print("The largest prime factor is", prime_factors[-1])
更困难的问题可能需要不同的算法 查看此问题: 您的代码看起来不错,但可能需要很长时间才能完成一个大的
。利用数学可以使您更快地解决这个问题 在这个链接上,我建议纯python解决方案使用n
,而使用numpy的解决方案则使用rwh_primes1
。这两种实现都相当简短,相对清晰,基本上做的是相同的事情。这些代码片段是用python 2编写的,因此翻译可能如下:primesfrom3to
def rwh_primes1(n): sieve = [True] * (n//2) for i in range(3, int(n**0.5)+1,2): if sieve[i//2]: sieve[i*i//2::i] = [False] * ((n-i*i-1)//(2*i)+1) return [2] + [2*i+1 for i in range(1,n//2) if sieve[i]]
更困难的问题可能需要不同的算法 查看此问题: 您的代码看起来不错,但可能需要很长时间才能完成一个大的
。利用数学可以使您更快地解决这个问题 在这个链接上,我建议纯python解决方案使用n
,而使用numpy的解决方案则使用rwh_primes1
。这两种实现都相当简短,相对清晰,基本上做的是相同的事情。这些代码片段是用python 2编写的,因此翻译可能如下:primesfrom3to
def rwh_primes1(n): sieve = [True] * (n//2) for i in range(3, int(n**0.5)+1,2): if sieve[i//2]: sieve[i*i//2::i] = [False] * ((n-i*i-1)//(2*i)+1) return [2] + [2*i+1 for i in range(1,n//2) if sieve[i]]
代码的另一个可能会减慢速度的方面是代码的后半部分
特别是声明largest = 0 n = 600851475143 for i in range(2,n-1): if isPrime(i) and n % i == 0: largest = i n = n / i continue
根据,仅当第一个条件为if isPrime(i) and n % i == 0:
时,才会计算第二个条件。在您的情况下,更合理的做法是反转条件,以便始终执行计算上昂贵的除法,并且更昂贵的True
仅为calisPrime()
- 所有因子分解只需达到