要求
给定一个数字 n,编写一个有效的函数来打印 n 的所有质因数。
例如,如果输入数字为 12,则输出应为“2 2 3”。如果输入数字为 315,则输出应为“3 3 5 7”。以下是查找所有质因数的步骤。
1) 当 n 能被 2 整除时,打印 2 并将 n 除以 2。
2) 在第 1 步之后,n 必须为奇数。现在开始一个从 i = 3 到 n 的平方根的循环。当 i 除以 n 时,打印 i 并将 n 除以 i,将 i 乘以 2 并继续。
3)如果n是素数并且大于2,那么n不会通过上述两步变成1。因此,如果它大于 2,则打印 n。
常规方法
import math
# 打印所有素数的函数
# 定义给定的数字n
def primeFactors(n):
# 打印n除2的数字
while n % 2 == 0:
print(2)
n = n // 2
# n 是奇数
# 因此可以使用2(i=i+2)
for i in range(3,int(math.sqrt(n))+1,2):
# i除以n, print i ad divide n
while n % i== 0:
print(i)
n = n // i
# 如果N是素数
# > 2的数字
if n > 2:
print(n)
n = 315
primeFactors(n)
输出:
3 3 5 7
原理
步骤 1 和 2 负责合数,步骤 3 负责质数。为了证明完整的算法有效,我们需要证明步骤 1 和 2 实际上处理了复合数。很明显,第 1 步处理偶数。在第 1 步之后,所有剩余的质因数都必须是奇数(两个质因数的差必须至少为 2),这就解释了为什么 i 以 2 递增。
循环一直运行到 n 的平方根,而不是直到 n。
为了证明这种优化有效,要考虑复合数的以下属性:
每个合数至少有一个质因数小于或等于自身的平方根。
可以使用反语句来证明此属性。设 a 和 b 是 n 的两个因数,使得 a*b = n。如果两者都大于 √n,则 a.b > √n, * √n,这与表达式“a * b = n”相矛盾。
在上述算法的第 2 步中,我们运行一个循环并执行循环中的跟随
a) 求最小质因数 i(必须小于 √n,)
b) 通过重复将 n 除以 i 从 n 中删除所有出现的 i。
c) 重复步骤 a 和 b 除以 n 和 i = i + 2。重复步骤 a 和 b,直到 n 变为 1 或质数。
使用厄拉托塞师(埃拉托斯特尼筛法)筛法
这种方法打印给定数字“n”的所有质因数。它首先初始化一个数组“spf”,其索引从 0 到 n+1,值设置为 0。然后,它将“i”的值分配给数组中从 2 到 n 的所有“i”的相应索引。对于偶数,值 2 分配给数组中的相应索引。然后,对于从 3 到 'n' 的平方根的所有奇数 'i',检查数组索引 'spf[i]',如果它等于 'i',则检查从 'i*i' 到 'n' 范围内的所有 'i' 的倍数,并将其对应的数组值设置为 'i'。最后,使用数组“spf”打印给定数字的质因数。
原理
1. 创建一个布尔数组“prime[0..n]”,并将其初始化为true。
2. 将 2、3、5、...、sqrt(n) 的所有倍数标记为非素数。在这里,我们不是标记,而是存储每个合数的最小质因数。
3. 在 i 除以 n 时,将数组从最小的质因数 i 遍历到 sqrt(n)。n 的最小质因数将是质因数。
4. 如果 n 是质数且大于 2,则 n 不会通过上述两步变成 1。因此,如果它大于 2,则打印 n。
def primeFactors(n):
spf = [0 for i in range(n+1)]
spf[1] = 1
for i in range(2, n+1):
spf[i] = i
for i in range(4, n+1, 2):
spf[i] = 2
for i in range(3, int(n**0.5)+1):
if spf[i] == i:
for j in range(i*i, n+1, i):
if spf[j] == j:
spf[j] = i
while n != 1:
print(spf[n], end=" ")
n = n // spf[n]
n = 315
primeFactors(n)
输出
3 3 5 7
使用匿名函数
该方法使用匿名函数来生成给定数字的所有质因数。然后,它使用 while 循环和 for 循环重复调用该函数并将因子追加到列表中,直到给定的数字 n 减少到 1。最后,它打印用空格分隔的 n 的质因数。
原理
1. 定义一个匿名函数prime_factors,该函数将正整数 n 作为输入并生成 n.2
的所有质因数。初始化空列表因子。
3. 使用 while 循环重复调用 prime_factors 函数并将因子附加到因子中,直到 n 减少到 1。
4. 在 while 循环中,使用 for 循环遍历 prime_factors 函数生成的 n 的质因数。
5. 将每个因子附加到因子中,并通过将其除以因子来更新 n。
6. 使用带有 * 运算符的 print 函数打印用空格分隔的 n 的质因数,以将因数列表解压缩为参数。
# Using anonymous function
prime_factors = lambda n: [i for i in range(2, n+1) if n%i == 0 and all(i % j != 0 for j in range(2, int(i**0.5)+1))]
n = 315
factors = []
while n > 1:
for factor in prime_factors(n):
factors.append(factor)
n //= factor
print(*factors)
输出
3 5 7 3