质数相关算法:求整数n的所有质因子

题目描述

功能:输入一个正整数,按照从小到大的顺序输出它的所有质因子(重复的也要列举)(如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()
  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值