第三个问题如下:
13195的主要因素是5,7,13和29.最大的是什么 数字的主要因素600851475143?
我的解决方案代码如下。但它太慢了,我认为需要数周才能完成。 我怎样才能改进它?或者Python本身太慢,无法解决这个问题?
def IsPrime(num):
if num < 2:
return False
if num == 2:
return True
else:
for div in range(2,num):
if num % div == 0:
return False
return True
GetInput = int (input ("Enter the number: "))
PrimeDivisors = []
for i in range(GetInput, 1, -1):
print(i)
if GetInput % i == 0 and IsPrime(i) is True:
PrimeDivisors.append(i)
break
else:
continue
print(PrimeDivisors)
print("The greatest prime divisor is:", max(PrimeDivisors))
答案 0 :(得分:2)
你的解决方案的问题在于你没有考虑到你发现的素因子,所以在你真正找到最大因素之后你就会不必要地检查因素。这是我的解决方案:
def largest_prime_factor(n):
largest = None
for i in range(2, n):
while n % i == 0:
largest = i
n //= i
if n == 1:
return largest
if n > 1:
return n
项目欧拉问题更多的是关于数学而不是编程,所以如果你的解决方案太慢,那可能不是你的语言有问题。
请注意,我的解决方案很快就会针对此特定数字运行,因此它绝对不是一般解决方案。更快的解决方案are complicated并且在这种特定情况下过度杀伤。
答案 1 :(得分:1)
这可能不是最快的算法,但它非常有效:
def prime(x):
if x in [0, 1]:
return False
for n in xrange(2, int(x ** 0.5 + 1)):
if x % n == 0:
return False
return True
def primes():
"""Prime Number Generator
Generator an infinite sequence of primes
http://stackoverflow.com/questions/567222/simple-prime-generator-in-python
"""
# Maps composites to primes witnessing their compositeness.
# This is memory efficient, as the sieve is not "run forward"
# indefinitely, but only as long as required by the current
# number being tested.
#
D = {}
# The running integer that's checked for primeness
q = 2
while True:
if q not in D:
# q is a new prime.
# Yield it and mark its first multiple that isn't
# already marked in previous iterations
#
yield q
D[q * q] = [q]
else:
# q is composite. D[q] is the list of primes that
# divide it. Since we've reached q, we no longer
# need it in the map, but we'll mark the next
# multiples of its witnesses to prepare for larger
# numbers
#
for p in D[q]:
D.setdefault(p + q, []).append(p)
del D[q]
q += 1
def primefactors(x):
if x in [0, 1]:
yield x
elif prime(x):
yield x
else:
for n in primes():
if x % n == 0:
yield n
break
for factor in primefactors(x // n):
yield factor
<强>用法:强>
>>> list(primefactors(100))
[2, 2, 5, 5]
答案 2 :(得分:1)
我的代码对我来说似乎足够快。使用collections.defaultdict()可以使primes()的代码更加清晰,但我想代码会因为导入代码而失去一些速度。
def primes():
"""Prime number generator."""
n, skip = 2, {}
while True:
primes = skip.get(n)
if primes:
for p in primes:
skip.setdefault(n + p, set()).add(p)
del skip[n]
else:
yield n
skip[n * n] = {n}
n += 1
def un_factor(n):
"""Does an unique prime factorization on n.
Returns an ordered tuple of (prime, prime_powers)."""
if n == 1:
return ()
result = []
for p in primes():
(div, mod), power = divmod(n, p), 1
while mod == 0:
if div == 1:
result.append((p, power))
return tuple(result)
n = div
div, mod = divmod(n, p)
if mod != 0:
result.append((p, power))
power += 1
试运行:
>>> un_factor(13195)
((5, 1), (7, 1), (13, 1), (29, 1))
>>> un_factor(600851475143)
((71, 1), (839, 1), (1471, 1), (6857, 1))
>>> un_factor(20)
((2, 2), (5, 1))
编辑:基于this食谱的primes()生成器的微小编辑。
EDIT2:固定为20。
EDIT3:用un_factor()替换了great_prime_divisor()。
答案 3 :(得分:0)
def getLargestFactor(n):
maxFactor = sqrt(n)
lastFactor = n
while n%2 == 0:
n /= 2
lastFactor = 2
for i in xrange(3,int(maxFactor),2 ):
if sqrt(n) < i:
return n
while n%i == 0 and n > 1:
n /= i
lastFactor = i
return lastFactor
这应该相当有效。将每个因素全部分开,这样我们只找到素因子。并且使用的事实是,只有一个大于sqrt(n)的数的素因子。