我正在努力通过解决Project Euler问题来提高我的数学/编码/解决问题的能力,而且我对第三个问题有点困惑。问题是“13195的主要因素是5,7,13和29. 600851475143中最大的主要因素是什么?”
到目前为止,这是我的代码
import math
def isPrime(n):
if n > 1:
for i in range(2, n):
if n % i == 0:
return False
else:
return True
else:
return False
def highFactor(m):
factors = []
for i in range(2, int(math.sqrt(m))):
if isPrime(i):
if m % i == 0:
factors.append(i)
print max(factors)
highFactor(13195)
所以这显然是在测试他们给出的例子,因为我已经知道答案应该是29,但是当我运行代码时它给了我91.我做错了什么?
答案 0 :(得分:1)
两个问题:
(1)你的isPrime函数在循环的第一次迭代时返回True。你反而希望完成循环,然后如果你在整个循环中存活而没有返回false,则返回True。
(2)算法可能具有相同素数因子的多个副本(即8 = 2 * 2 * 2)。你最好设置m = m / i并每次重启循环。此外,您可能希望sqrt(m)+1,因为范围函数不包括上限。
答案 1 :(得分:0)
如评论中所述,您的函数过早返回True - 例如如果一个数字不能被2除,那并不意味着它不会被范围(2,n)中任何后来的数字整除 - 考虑51 = 3 * 17作为反例。
以下是您算法的正确版本:
private static string _plotsByReview = @"
select
g.GraphId,
g.GraphName,
g.UserId,
g.Shared,
g.ReviewId,
p.PlotId as Plots__PlotId,
p.GraphId as Plots__GraphId,
p.TagId as Plots__TagId,
p.YAxis as Plots__YAxis,
p.Relabel as Plots__Relabel,
p.Scale as Plots__Scale,
p.MinY as Plots__MinY,
p.MaxY as Plots__MaxY
from [Graph] g
inner join [Plot] p on p.GraphId = g.GraphId
where g.ReviewId = @0
";
正如其他人所提到的,有一种更快捷的方法来检查数字是否为素数;现在你的函数的复杂度为def isPrime(n):
if n > 1:
for i in range(2, n):
if n % i == 0:
return False
return True
else: # if we have a negative number or 0
return False
,因为你检查的所有数字都是n;通过观察,O(n)
足以检查n = sqrt(n) * sqrt(n)
sqrt(n) + 1
答案 2 :(得分:0)
正如奥斯丁评论isPrime
太早回归真实。通过将return True
移到for
循环之外,您的函数将在确认该数字为素数之前检查range(2, n)
中的每个数字。
说你应该isPrime(13)
返回True
for
循环if n % i == 0
的第一遍将是if 13 % 2 == 0
,这是假的。由于else: return True
循环中的for
,该函数将返回True
并终止。
要解决此问题,您可以编写isPrime()
之类的内容:
def isPrime(n):
if n > 1:
for i in range(2, n):
if n % i == 0:
return False
return True
else:
return False