【问题标题】:Finding the largest prime factor of 13195找到 13195 的最大素数
【发布时间】:2021-03-17 16:06:48
【问题描述】:

我正在尝试解决 Project Euler 存档中的一个问题:https://projecteuler.net/problem=3

13195 的质因数是 5、7、13 和 29。 600851475143这个数的最大质因数是多少?

我尝试先求解 13195。我最初的想法是创建一个包含所有低于给定数字的素数的列表。我使用 Erathostenes 算法的筛子来做到这一点。然后,使用 for 循环,我遍历所有这些素数,将作为给定数字的因子的素数添加到单独的列表中。我对列表进行了排序并打印了最大的因素。当我运行脚本时,我在因子列表中得到了一个额外的数字,它不是给定数字的因子。

对于num = 13915,输出应该是 [13, 29, 5, 7] 但我得到的是 [13, 29, 377, 5, 7]

我无法弄清楚 377 的来源。我知道我的解决方案不是最有效的,但我尝试自己解决这个问题。所以我的问题是:

377 是从哪里来的? 您能提出一个更有效的方法来解决这个问题吗?

对于给您带来的不便,我深表歉意,因为我是使用 Python 解决问题的新手。

primes = []
num = 13195
factors = []
for i in range(1, num + 1):
    #sieve of erathostenes
    if i % 2 != 0 and i % 3 != 0 and i % 5 != 0 and i % 7 != 0 and i != 1:
        primes.append(i)

if num >= 10:
    primes.append(2)
    primes.append(3)
    primes.append(5)
    primes.append(7)

sorted(primes)

for i in range(len(primes)):
    prime = primes[i]
    if num % prime == 0:
        factors.append(primes[i])


print(factors)
factors.sort()
print(factors[len(factors) - 1])

【问题讨论】:

  • sorted(primes) 什么都不做,因为你没有将结果分配给任何东西。
  • 在一个数字下面找到 all 素数以分解它似乎有点矫枉过正。此外,i % 2 != 0 and i % 3 != 0 and i % 5 != 0 and i % 7 != 0 不是测试某物是否为素数的方法。请注意377 = 13*29,但您的代码将其归类为素数。
  • 为了更有效地生成素数,我们有两个问题的答案非常好:stackoverflow.com/questions/2068372/…stackoverflow.com/questions/2211990/…

标签: python


【解决方案1】:

您不需要生成素数。对数字进行直接因式分解会更有效:

def primeFactors(N):  # generator for all prime factors
    p = 2
    while p*p<=N:       # only need up to √N (remaining N)
        while N%p == 0: # p is a factor (will be a prime)
            yield p     # return primes as many times as they appear
            N //= p     # remove the prime factor from the number
        p += 1 + p%2    # next potential prime
    if N>1: yield N     # beyond √N whatever remains is a prime factor

输出:(取找到的最大因子)

print(max(primeFactors(600851475143))) # 6857

【讨论】:

  • 你甚至不需要取最大值,因为你是按顺序生成它们的。最大值应该是最后一个。
  • 我不确定while 循环是否是这里的最佳选择,我可能使用过for p in itertools.chain([2], range(3, math.ceil(math.sqrt(N)), 2))
  • 我同意该函数可以专门用于仅返回最后一个(最大)因子。然而,while 循环很有用,因为在这个过程中 N 会减少(当我们找到因数时),这大大减少了迭代次数。除非我们设置一个中断条件,否则 for 循环将不允许这样做,这会将它变成一个混蛋的 while 循环。
  • 此外,该链技巧需要使用 chain.from_iterables 否则它会在继续之前创建一个包含所有潜在因素的内部列表。我过去曾尝试过,并且有更快的解决方案可以通过两个素数 2 步进。微不足道的速度差异使我最终保持最简单的形式。
  • 我错过了 N 正在减少的事实,忘记我说了什么。
【解决方案2】:

使用它来获取从大到小排序的数字的因子

number = 13915
list_of_factors=sorted([int(number/n) for n in range(2,number//2 +1) if number % n ==0 ],reverse=True) 

结果是 [2783, 1265, 605, 253, 121, 115, 55, 23, 11, 5]

【讨论】:

  • 对于600851475143,您的理解可能会迭代超过 3000 亿次 n。说这不是获取6857 (the largest prime factor) 的有效方法是轻描淡写。此外,您仍然需要过滤返回的列表以发现哪些因素是素数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-28
  • 2021-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-22
相关资源
最近更新 更多