我在我找到的网站上做了这个问题(项目Euler),并且有一个问题涉及找到一个数字的最大素数因子。我的解决方案失败了很多,所以我想知道如何简化这段代码?
""" Find the largest prime of a number """
def get_factors(number):
factors = []
for integer in range(1, number + 1):
if number%integer == 0:
factors.append(integer)
return factors
def test_prime(number):
prime = True
for i in range(1, number + 1):
if i!=1 and i!=2 and i!=number:
if number%i == 0:
prime = False
return prime
def test_for_primes(lst):
primes = []
for i in lst:
if test_prime(i):
primes.append(i)
return primes
################################################### program starts here
def find_largest_prime_factor(i):
factors = get_factors(i)
prime_factors = test_for_primes(factors)
print prime_factors
print find_largest_prime_factor(22)
#this jams my computer
print find_largest_prime_factor(600851475143)
使用大数字时失败,这是我猜的问题。 (计算机堵塞,告诉我我的内存已用完,并询问我想停止哪些程序)。
************************************ 感谢您的回答。在任何情况下,代码中都存在一些错误。所以这个(低效代码)的固定版本在下面。
""" Find the largest prime of a number """
def get_factors(number):
factors = []
for integer in xrange(1, number + 1):
if number%integer == 0:
factors.append(integer)
return factors
def test_prime(number):
prime = True
if number == 1 or number == 2:
return prime
else:
for i in xrange(2, number):
if number%i == 0:
prime = False
return prime
def test_for_primes(lst):
primes = []
for i in lst:
if test_prime(i):
primes.append(i)
return primes
################################################### program starts here
def find_largest_prime_factor(i):
factors = get_factors(i)
print factors
prime_factors = test_for_primes(factors)
return prime_factors
print find_largest_prime_factor(x)
答案 0 :(得分:6)
根据您的方法,您首先在n
中生成数字O(n)
的所有除数,然后在O(n)
的另一test_prime
次调用中测试这些除数中的哪一个是素数(无论如何都是指数)。
更好的方法是观察一旦你发现一个数的除数,你可以反复除以它来摆脱所有这些因素。因此,为了获得主要因素,比如830297
,你测试所有的小素数(缓存),并且对于每个分数你的数字,你要继续划分:
830297
可被13
整除,所以现在您将使用830297 / 13 = 63869
63869
仍可13
整除,您在4913
4913
不会除以13,下一个素数是17
,它将4913
除以289
289
仍然是17
的倍数,你有17
这是除数并停止。为了进一步提高速度,在测试下面的缓存素数100
之后,你必须使用test_prime
函数测试素数除数(根据@ Ben的答案更新),但继续反向,从sqrt
开始。您的号码可以被71
整除,下一个号码会sqrt
91992
,这有点接近6857
,这是最大的素数因素。
答案 1 :(得分:5)
这是我最喜欢的Python简单分解程序:
def factors(n):
wheel = [1,2,2,4,2,4,2,4,6,2,6]
w, f, fs = 0, 2, []
while f*f <= n:
while n % f == 0:
fs.append(f)
n /= f
f, w = f + wheel[w], w+1
if w == 11: w = 3
if n > 1: fs.append(n)
return fs
基本算法是试验分割,使用素轮产生试验因子。它并不像素数的试验划分那么快,但是不需要计算或存储素数,所以它非常方便。
如果您对使用素数进行编程感兴趣,可以在我的博客上欣赏此essay。
答案 2 :(得分:5)
我的解决方案是在C#中。我打赌你可以把它翻译成python。我已经用1到1.000.000.000之间的随机长整数进行测试,并且表现良好。您可以尝试使用在线prime calculator快乐编码来测试结果:)
public static long biggestPrimeFactor(long num) {
for (int div = 2; div < num; div++) {
if (num % div == 0) {
num \= div
div--;
}
}
return num;
}
答案 3 :(得分:4)
可以通过以下几种方式改进幼稚素性测试:
除了这些简单的修复之外,您还必须查找更有效的分解算法。
答案 4 :(得分:3)
使用Sieve of Eratosthenes来计算素数。
from math import sqrt
def sieveOfEratosthenes(n):
primes = range(3, n + 1, 2) # primes above 2 must be odd so start at three and increase by 2
for base in xrange(len(primes)):
if primes[base] is None:
continue
if primes[base] >= sqrt(n): # stop at sqrt of n
break
for i in xrange(base + (base + 1) * primes[base], len(primes), primes[base]):
primes[i] = None
primes.insert(0,2)
return filter(None, primes)
答案 5 :(得分:3)
通过试验划分进行素数分解的要点是,仅对一个数字进行因子分解的最有效解决方案不需要任何质数测试。
您只需按升序列举您的可能因素,并将它们从有问题的数字中分开 - 所有这些因素都可以保证是最优的。当当前因子的平方超过被分解的当前数时停止。请参阅user448810's answer中的代码。
通常情况下,试验除法的素数因子化在素数上比在所有数字(或赔率等)上更快,但是当仅对一个数字进行因子分解时,为了先找出要素除以后的次数,将 可能的成本高于不断增加的可能因素。此枚举为 O(n),素数生成为 O(n log log n),带the Sieve of Eratosthenes (SoE),其中 n = sqrt(N) 的上限为 N 。通过试验区(TD),复杂度为 O(n 1.5 /(log n) 2 )。
当然,渐近线只是作为指导,实际代码的常数因素可能会改变图像。例如,从here和here派生的Haskell代码的执行时间,分解600851475149(素数):
2.. 0.57 sec
2,3,5,... 0.28 sec
2,3,5,7,11,13,17,19,... 0.21 sec
primes, segmented TD 0.65 sec first try
0.05 sec subsequent runs (primes are memoized)
primes, list-based SoE 0.44 sec first try
0.05 sec subsequent runs (primes are memoized)
primes, array-based SoE 0.15 sec first try
0.06 sec subsequent runs (primes are memoized)
所以这取决于。当然,将所讨论的复合数量分解为600851475143几乎是瞬时的,因此无关紧要。
答案 6 :(得分:3)
Here is an example in JavaScript
function largestPrimeFactor(val, divisor = 2) {
let square = (val) => Math.pow(val, 2);
while ((val % divisor) != 0 && square(divisor) <= val) {
divisor++;
}
return square(divisor) <= val
? largestPrimeFactor(val / divisor, divisor)
: val;
}
答案 7 :(得分:1)
我将解决方案从@ under5hell转换为Python(2.7x)。多么有效的方式!
java.util.Random
答案 8 :(得分:1)
试试这段代码:
from math import *
def largestprime(n):
i=2
while (n>1):
if (n % i == 0):
n = n/i
else:
i=i+1
print i
strinput = raw_input('Enter the number to be factorized : ')
a = int(strinput)
largestprime(a)
答案 9 :(得分:0)
旧的但可能有帮助
def isprime(num):
if num > 1:
# check for factors
for i in range(2,num):
if (num % i) == 0:
return False
return True
def largest_prime_factor(bignumber):
prime = 2
while bignumber != 1:
if bignumber % prime == 0:
bignumber = bignumber / prime
else:
prime = prime + 1
while isprime(prime) == False:
prime = prime+1
return prime
number = 600851475143
print largest_prime_factor(number)
答案 10 :(得分:0)
我希望这会有所帮助,也很容易理解。
A = int(input("Enter the number to find the largest prime factor:"))
B = 2
while (B <(A/2)):
if A%B != 0:
B = B+1
else:
A = A/B
C = B
B = 2
print (A)
答案 11 :(得分:0)
这个用于获取最大素数因子的代码,当我运行它时,其值为prime_factor(13195),将在不到一秒的时间内返回结果。 但是当nums值达到6digits时,它将在8秒内返回结果。
任何人都知道解决方案的最佳算法是什么......
def prime_factor(nums):
if nums < 2:
return 0
primes = [2]
x = 3
while x <= nums:
for i in primes:
if x%i==0:
x += 2
break
else:
primes.append(x)
x += 2
largest_prime = primes[::-1]
# ^^^ code above to gets all prime numbers
intermediate_tag = []
factor = []
# this code divide nums by the largest prime no. and return if the
# result is an integer then append to primefactor.
for i in largest_prime:
x = nums/i
if x.is_integer():
intermediate_tag.append(x)
# this code gets the prime factors [29.0, 13.0, 7.0, 5.0]
for i in intermediate_tag:
y = nums/i
factor.append(y)
print(intermediate_tag)
print(f"prime factor of {nums}:==>",factor)
prime_factor(13195)
[455.0,1015.0,1885.0,2639.0] 素因子13195:==&gt; [29.0,13.0,7.0,5.0]