题目描述
功能:输入一个正整数,按照从小到大的顺序输出它的所有质因子(重复的也要列举)(如180的质因子为2 2 3 3 5 )
最后一个数后面也要有空格
数据范围: 1≤n≤2×10**9+14
输入描述:
输入一个long型整数
输出描述:
按照从小到大的顺序输出它的所有质数的因子,以空格隔开。最后一个数后面也要有空格。
示例1
输入:180
输出:2 2 3 3 5
整数质因子的核心判断:
1、能被该整数整除;
2、是质数(素数)
思路一:
1、先找出该整数下的所有质数,再逐一判断是否能被该整数整除,最后得到所有质因子;
2、先找出该整数下最大的质因子, 用它整除后的商继续循环,找到最大的质因子,直到最后找出的最大质因子是它自己;
思路二:
1、先找出小于这个整数的所有质数,再判断是否为该整数的因子(是否能被整除);
2、先找出这个整数的所有因子,再判断因子是否为质数
以下解法均使用思路一
解法1:
只用试除法,时间复杂度较大,大于n
number = int(input())
nb_list = []
while number != 1:
# 从小到大进行判断,如果一个因子是合数,必然在前面就被除掉了,因此过滤出来的都是质数, 只需试除到根号number
for i in range(2, int(number**0.5)+1):
# print(number, i)
if number%i == 0:
nb_list.append('%s'%i)
number = number//i
# print(number)
break
print(' '.join(nb_list)+' ')
解法2:
用试除法加因式分解的数学常识,试除范围按几何倍数缩小,时间复杂度较小,根号n
试除法:如果有整数number作为被除数,可以把2到number之间每个数作为除数逐一试除,如果能被整除,就把除数记录下来,
继续循环,把商赋值给被除数number,重复这个过程,最终记录的所有除数,就是number的质因子
为什么看起来没有过滤掉合数因子,可最终的因子不可能是合数因子,因为合数一定是可以分解为2个小于它的质数相乘的,前面试除小于它的每个数时,必然能试除成功,因此该合数因子会被拆分。
例如:假设我们求的是8的质因子,你可能觉得程序有可能会算出44的结果,但其实不可能,因为4本身是合数,合数一定是可以分解为2个小于它的质数相乘的,4=22,所以当我们用这个逻辑去求8的质因子时,从2开始试除,8/2=4,接着把4赋值给number,又重新从2开始试除,得到4/2=2,所以合数在这个过程中,必然会被拆分为2个质数相乘的。
数学常识:对number进行因式分解时,如果我们分解出一个小于根号number的因子,必然会有一个大于根号number的因子成对出现。
例如:number=16,可以拆分为1*16, 2*8, 4*4。
由此规律,我们可以判断,number在试除大于2并且小于或等于根号number范围内的数时,如果没有一个能被整除,则代表大于或等于根号number且小于number范围内的数也无法被number整除,据此可判断该数为质数。(此规律可缩小试除的范围)
number = int(input())
nb_list = []
while number != 1:
# 从小到大进行试除,如果一个因子是合数,必然在前面就被除掉了,例如合数因子4,会在前面遇到2的时候就被除掉了,因此过滤出来的都是质数
# 最大范围只需试除到根号number
for i in range(2, int(number**0.5)+1):
# print(number, i)
if number%i == 0:
nb_list.append('%s'%i)
number = number//i
# print(number)
break
if i == int(number**0.5): # 当i 走到这里,也就表明2到根号number范围内没有能被整除的数,所以number本身已经是质数
nb_list.append('%s' % number)
number = 1 # 跳出大循环
print(' '.join(nb_list)+' ')
# 试算 180, 2000000000, 64577
网友写法:在判断是否质数的同时,缩小了范围。仔细看逻辑跟我的解法2一样,只是写法稍微不同而已
def func():
num = int(input())
def getprime(n):
i = 2
while i * i <= n and n >= i:
while n % i == 0:
n = n // i
print(i, end=" ")
i = i + 1
if n - 1:
print(n, end=" ")
getprime(num)
if __name__ == "__main__":
func()