我刚刚完成了第三个项目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不会使产品大于目标数。
我有一种感觉,这可能只是完全解决问题的错误方法,但我仍然坚持要改变什么。
答案 0 :(得分:1)
您应该使用模数运算符%。假设你有一个数字270.所以,你将270除以3直到它被剥离&#34;关闭3,即。没有因素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
备注强>
不要使用浮点数来解决数论问题。首先,模运算符不会对它们起作用。其次,你永远不知道什么时候你是精确度不准确的受害者。示例:0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1==1.0
评估为False.
如果您需要检查divisibility,请使用%。
您的代码失败的原因是正确的。对于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