计算素因子的算法建议(Python初学者)

时间:2018-01-10 03:59:12

标签: python

SPOILER ALERT!这可能会影响你的回答#3

我设法获得了一段代码,但由于我正在分析的数量很多,因此计算解决方案需要花费很长时间。

我觉得蛮力不是正确的方法......

有助于提高此代码的效率吗?

# What is the largest prime factor of the number 600851475143

# Set variables
number = 600851475143
primeList = []
primeFactorList = []

# Make list of prime numbers < 'number'
for x in range(2, number+1):
    isPrime = True
    # Don't calculate for more than the sqrt of number for efficiency
    for y in range(2, int(x**0.5)+1):
        if x % y == 0:
            isPrime = False
            break
    if isPrime:
        primeList.append(x)

# Iterate over primeList to check for prime factors of 'number'
for i in primeList:
    if number % i == 0:
        primeFactorList.append(i)

# Print largest prime factor of 'number'
print(max(primeFactorList))

4 个答案:

答案 0 :(得分:1)

您可以使用用户定义的功能,例如

<head>
    <script>
        function add() {
        var lookupType = document.getElementById("lookupType");
        var typeID = -1;
        if (lookupType != null) typeID = lookupType.value;
        document.forms[0].action = "ManageLookupSupport!add.action?" + encodeURI("keyValue.keyType=" + typeID);
        document.forms[0].submit();
         }
    </script>
</head>

<div class="container-fluid" id="page">
   <div id="page-wrapper">
      <s:form theme="simple">
         <div class="panel-body" align="center">
            <s:submit cssClass="btn btn-primary" value="Add"
                onclick="javascript:add();return false" 
                data-toggle="modal" data-target="#lookupModal"/>                      
         </div>
      </s:form>
   </div>
</div>

它将返回布尔值。您可以使用此功能来验证素因子。

OR

你可以连续将数字除以2

def isprime(n):
if n < 2:
    return False
for i in range(2,(n**0.5)+1):
    if n % i == 0:
        return False

return True

n必须是奇数现在跳过2 in for循环,然后打印每个除数

n = 600851475143
while n % 2 == 0:
    print(2),
    n = n / 2

此时,n将等于1,除非n是素数。所以

for i in range(3,n**0.5+1,2):
    while n % i== 0:
        print(i)
        n = n / i

将自己打印为主要因素。

玩得开心

答案 1 :(得分:1)

我首先要解决您尝试的特定算法中的一些基本问题:

您不需要预先生成素数。在您需要的时候即时生成它们 - 您还会看到您生成的素数超出了您的需求(您只需要尝试素数到sqrt(600851475143)

# What is the largest prime factor of the number 600851475143

# Set variables
number = 600851475143
primeList = []
primeFactorList = []

def primeList():
    # Make list of prime numbers < 'number'
    for x in range(2, number+1):
        isPrime = True
        # Don't calculate for more than the sqrt of number for efficiency
        for y in range(2, int(x**0.5)+1):
            if x % y == 0:
                isPrime = False
                break
        if isPrime:
            yield x

# Iterate over primeList to check for prime factors of 'number'
for i in primeList():
    if i > number**0.5:
        break
    if number % i == 0:
        primeFactorList.append(i)

# Print largest prime factor of 'number'
print(max(primeFactorList))

使用生成器(请参阅yield?)PrimeList()甚至可以通过将质数更改为永久返回素数:

def primeList():
    x = 2
    while True:
        isPrime = True
        # Don't calculate for more than the sqrt of number for efficiency
        for y in range(2, int(x**0.5)+1):
            if x % y == 0:
                isPrime = False
                break
        if isPrime:
            yield x
        x += 1

虽然我无法帮助,但稍微优化它以跳过大于2的偶数:

def primeList():
    yield 2
    x = 3
    while True:
        isPrime = True
        # Don't calculate for more than the sqrt of number for efficiency
        for y in range(2, int(x**0.5)+1):
            if x % y == 0:
                isPrime = False
                break
        if isPrime:
            yield x
        x += 2

如果你放弃了枚举素数的初步想法并一次针对number尝试一个素数,那么还有另一种选择:相反直接处理number并将其排除在外 - 即,做什么botengboteng suggests并直接分解数字。

这会快得多,因为我们现在检查的数字要少得多:

number = 600851475143                                                           

def factors(num):                                                               
    factors = []                                                                
    if num % 2 == 0:                                                            
        factors.append(2)                                                       
    while num % 2 == 0:                                                         
        num = num // 2                                                          
    for f in range(3, int(num**0.5)+1, 2):                                      
        if num % f == 0:                                                        
            factors.append(f)                                                   
        while num % f == 0:                                                     
            num = num // f
         # Don't keep going if we're dividing by potential factors               
         # bigger than what is left.                                             
         if f > num:
            break                                                      
    if num > 1:                                                                 
        factors.append(num)                                                     
    return factors                                                              

# grab last factor for maximum.                                                                                
print(factors(number)[-1])

答案 2 :(得分:0)

首先计算你的数字的sqrt。

number = 600851475143
number_sqrt = (number**0.5)+1

然后在您的最外层循环中,仅搜索值小于您的数字的sqrt根的素数。您将不需要任何高于此的素数。 (您可以根据您的列表推断任何更大的内容。)

for x in range(2, number_sqrt+1):

要推断最大因素,只需将您的数字除以因子列表中的项目,包括它们之间的任何组合,并确定结果是否为素数。

无需重新计算素数列表。但是要定义一个函数来确定数字是否为素数。

我希望我很清楚。祝好运。非常有趣的问题。

答案 3 :(得分:0)

我制作了这段代码,如果您有任何问题可以自由评论,一切都会被解释

def max_prime_divisor_of(n):
    for p in range(2, n+1)[::-1]: #We try to find the max prime who divides it, so start descending
        if n%p is not 0: #If it doesn't divide it does not matter if its prime, so skip it
            continue
        for i in range(3, int(p**0.5)+1, 2): #Iterate over odd numbers
            if p%i is 0:
                break #If is not prime, skip it
            if p%2 is 0: #If its multiple of 2, skip it
                break
        else: #If it didn't break it, is prime and divide our number, we got it
            return p #return it
        continue #If it broke, means is not prime, instead is just a non-prime divisor, skip it

如果你不知道:它在range(2, n+1)[::-1]中的作用与reversed(range(2, n+1))相同,所以这意味着不是以 2 < / strong>,它以 n 开头,因为我们正在搜索最大素数。 (基本上它会颠倒列表以便以这种方式开始)

编辑1:这个代码运行得越快,它的除数越多,否则速度非常慢,一般用途使用上面的代码

def max_prime_divisor_of(n): #Decompose by its divisor
    while True:
        try:
            n = next(n//p for p in range(2, n) if n%p is 0) #Decompose with the first divisor that we find and repeat
        except StopIteration: #If the number doesn't have a divisor different from itself and 1, means its prime
            return n

如果你不知道:它在next(n//p for p in range(2, n) if n%p is 0)中的作用是获得第一个除数为n的数字