我刚刚完成了第三个项目Euler问题,该问题要求您找到给定数字的最大素数。我做了一个函数,该函数返回一个数字的所有素数的列表。
例如,如果输入100,它将返回[2.0,5.0]
我想尝试并现在制作一个程序,该程序返回一个列表,其中素数出现次数与其指数相同。
因此,例如,输入100将会返回[2.0、2.0、5.0、5.0](因为100为2 ^ 2 * 5 * 2)。
我编写了一个函数,如果放入了包含素因子的列表和包含指数的列表,则可以正确地执行此操作。问题是我用来获取指数列表的函数是错误的。
我写的代码对于某些数字(18、36、50、54 ...)失败。
我是编程的新手,所以如果有人可以帮助我,我将非常感激。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23def 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
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不会使乘积大于目标数。
我觉得这可能完全是解决问题的错误方法,但是我坚持要改变的地方。
只是好奇:素数始终是整数,那么为什么要返回浮点数?
请修正您的缩进。
我认为它返回浮点数是因为我的函数找到质数因子的方式(可能不必要地令人费解),它会分割以查看答案是否为整数,但是如果我不使用浮点数除法,则答案始终是整数。 尽管它似乎并没有太大的区别,所以我就离开了。 我认为缩进现在也应该修复
相同的问题:stackoverflow.com/questions/28911925/
这样就可以完成工作。
可能会有更快的方法来权衡cpu的内存使用情况。在这里,我尝试将素数列表保持在足以进行因式分解的范围内。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52import 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]
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)
输出:
1
2
3
4
5
6
7cached 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]
谢谢,该链接也非常有用,我也一直在尝试学习如何在课程中使用NumPy,因此很高兴看到它可以如何应用。
您应该使用模运算符%。假设您有一个数字270。因此,您将270除以3,直到它被"剥离"为3。剩下3个因子。
270/3 = 90
90/3 = 30
30/3 = 10
10不能被3整除。
因此,270 = 10 * 33
使用主要因子函数:
1
2
3
4
5
6
7
8
9
10
11def 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.如果需要检查可除性,请使用%。
您对代码失败的原因很正确。对于18,prime_factors(18)=[2,3].自24 <18 <25。您的函数报告18中2的幂是4,这是错误的。
非常感谢! 这比我想做的要有意义得多,我已经使用了这段代码,现在可以完美地工作了。 了解浮动信息也真的很有用,这也解释了为什么我在尝试浮动时总是遇到错误!
因为您想知道这是否是解决问题的正确方法,所以我建议您编写一个类似的函数来计算素因,只需将它们中的每一个添加到列表中:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21def 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