如何计算给定数字的素因子的指数?

时间:2015-08-05 22:25:29

标签: python prime-factoring exponent

我刚刚完成了第三个项目Euler问题,要求您找到给定数字的最大素数因子。我创建了一个函数,它返回一个数字的所有素因子的列表。

例如,如果您输入100,则会返回[2.0,5.0]

我想尝试现在创建一个程序,该程序返回一个列表,其中素数因子与​​它们的指数出现的次数相同。

因此,例如,输入100将改为返回[2.0,2.0,5.0,5.0](因为100是2 ^ 2 * 5 * 2)。

如果包含素因子的列表和包含指数的列表被放入,我编写了一个正确执行此操作的函数。问题是我用来获取指数列表的函数是错误的。

我写的代码对某些数字(18,36,50,54 ......)失败。

我对编程很新,所以如果有人能帮助我,我会非常感激。

def p_fctr_exp(n):
    """Prime factorises n and gives the exponents of each factor"""
    l1 = prime_factors(n) #Initialisation of variables and lists ('prime_factors() ) is just the function I made which gives a list of the prime factors
    p = 1
    exp=[]
    result=[]
    for x in l1:    #This multiplies the prime factors together just once
        x = float(x)
        p = (p * x)
    for x in range(0,len(l1)):  
        """Loop which cycles through factors from smallest first and multiplies 
    the total by the factor until the point where one more would make it bigger
    than the target number. The number of cycles required is stored in the 
    list 'exp'""" 
        a=1
        while p<n:
            p = p*float(l1[x])
            a+=1
        if p == n:
            exp.append(a)
        elif x < len(l1)-1:
            exp.append(a-1)
    return exp

我认为问题出现在while循环中,因为它通过将乘积p乘以最低素数因子直到它变得太大然后向上移动到下一个素数因子来工作。问题是如果说正确的指数应为2,但将其增加到3不会使产品大于目标数。

我有一种感觉,这可能只是完全解决问题的错误方法,但我仍然坚持要改变什么。

3 个答案:

答案 0 :(得分:1)

您应该使用模数运算符%。假设你有一个数字270.所以,你将270除以3直到它被剥离&#34;关闭3,即。没有因素3。

  • 三分之二百七十= 90
  • 三分之九十= 30
  • 30/3 = 10
  • 10不能被3整除。

因此,270 = 10 * 3 3

使用素数因子函数:

def p_fctr_exp(n):
    primes = prime_factors(n)
    exp=[]

    for p in primes:
        e=0
            while (n%p==0):
            n=n//p       # since p still divides n,
            e+=1         # we divide n by p and increase the exponent
        exp.append(e)
    return exp

备注

  1. 不要使用浮点数来解决数论问题。首先,模运算符不会对它们起作用。其次,你永远不知道什么时候你是精确度不准确的受害者。示例:0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1==1.0评估为False.如果您需要检查divisibility,请使用%。

  2. 您的代码失败的原因是正确的。对于18,prime_factors(18)=[2,3].,因为2 4 &lt; 18&lt; 2 5 。你的函数报告18中2的幂是4,这是错误的。

答案 1 :(得分:1)

这将完成工作。

可能有faster ways to do this权衡cpu的内存使用量。在这里,我试图保持素数列表很小,如果它足以进行因子分解。

import math

class PrimeList():
    init_primes = [2,3,5,7,11,13,15,17,19,23]
    def __init__(self, n):
        self.primes = PrimeList.init_primes
        self.extend(n)

    def extend(self,n):
        n = int(n)
        nextnum = self.primes[-1]
        while(self.primes[-1]<n):
            nextnum += 2
            if self.check(nextnum):
                self.primes.append(nextnum)

    def check(self,n):
        n = int(n)
        limit = int(math.sqrt(n))
        return all((n%p for p in self.primes if p<=limit))

    def is_prime(self, n):
        n = int(n)
        self.extend(int(math.sqrt(n)))
        return self.check(n)

    def factors(self, n):
        n = int(n)
        x = n
        fact = dict()
        for p in self.primes:
            if p>x:
                break
            while x%p==0:
                x = x/p
                fact[p]=fact.get(p,0)+1
        if x>1:
            e = x if x!=n else int(math.sqrt(n))
            self.extend(e)
            return self.factors(n)
        return sorted(fact.items())



myprimes = PrimeList(25)
print "cached primes:"+str(myprimes.primes)
print "100 == "+str(myprimes.factors(100))
print "32768 == "+str(myprimes.factors(32768))
print "23! == "+str(myprimes.factors(math.factorial(23)))
print "cached primes: "+str(myprimes.primes)
print "10001 == "+str(myprimes.factors(10001))
print "cached primes:"+str(myprimes.primes)

输出:

cached primes:[2, 3, 5, 7, 11, 13, 15, 17, 19, 23, 29]
100 == [(2, 2), (5, 2)]
32768 == [(2, 15)]
23! == [(2, 19), (3, 9), (5, 4), (7, 3), (11, 2), (13, 1), (17, 1), (19, 1), (23, 1)]
cached primes: [2, 3, 5, 7, 11, 13, 15, 17, 19, 23, 29]
10001 == [(73, 1), (137, 1)]
cached primes:[2, 3, 5, 7, 11, 13, 15, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137]

答案 2 :(得分:0)

由于您想知道这是否是解决问题的正确方法,我建议您编写一个类似的函数来计算素数因子,只需将它们中的每一个添加到列表中:

def prime_factors_list(n):
    result = list()
    diviser = 2

    if n <= 0:
        return [] #empty list



    if n == 1:
        return [1]

    """We increment diviser when it does not divide n anymore"""
    while n != 1:
        if n % diviser == 0: # if 'diviser' divides n
            n = n / diviser
            result.append(diviser) # diviser works, we add it to the list
        else:
            diviser += 1 #diviser does not work, we try with a bigger one

    return result