如何找到一个数的所有质因数,以及如何快速判断一个数是不是质数

前情介绍

        今天遇到一个需求:找到一个数所有的质因数。

初步解决

        先定义一个判断质数的函数:

def is_Prime(number):
    i = 2
    count = 0
    while i < number:
        if number % i == 0 :
            count += 1
        i += 1
    if count > 0:
        return False
    else:
        return True

        接着定义一个寻找质因数的函数:

def find_Prime_Factor(number):
    i = 2
    while i < number + 1:
        if(number % i == 0):
            if is_Prime(i):
                print(i , end=" ")
        i += 1

        ok ,搞定了

进一步分析

        这个程序可以是可以,但是至少有两处可以改进的地方:

        首先,判断质数要遍历到number,也就是时间复杂度为O(n),通过改变while循环的条件可以把遍历数目变为number/2,时间复杂度记为O(n/2)【其实时间复杂度还是O(n)】:

while i < number // 2 + 1:

        然后,记得之前有一个方法是遍历到平方根就可以了,这个时候只需要遍历到\sqrt{n},这个时候和上面的相比就有本质的区别了,时间复杂度为O(\sqrt{n}):

while (i < int(math.sqrt(number)) + 1):

        在这里需要说明的两点:

        1、必须要把平方根取整

        2、后面的“ + 1 ”必须有        

         最后,质数判断基本已经到了最极限的水平了,当然可能还有更好的,笔者没学习到,如果有大佬,欢迎补充。

        那就是求因数需要优化了,这个时候参考上面求质数的过程,我们是否也可以通过这几方面来求呢?答案是肯定的,在此附上快速求一个数所有因数的代码:

def find_factors(num):
    factors = []
    for i in range(1, int(num ** 0.5) + 1):
        if num % i == 0:
            factors.append(i)
            if num // i != i:
                factors.append(num // i)
    factors.sort()
    return factors

        整合到找质因数的函数也比较容易:

def find_Prime_Factor(number):
    i = 2
    # while i < number + 1:
    while i < int(number ** 0.5) + 1:
        if(number % i == 0):
            if is_Prime(i):
                print(i, end=" ")
            if num // i != i:
                if is_Prime(num // i):
                    print(num // i , end=" ")
        i += 1

延伸阅读 

        1、什么是质因数

质因数(素因数或质因子)在数论里是指能整除给定正整数的质数。

除了1以外,两个没有其他共同质因子的正整数称为互质。

因为1没有质因子,1与任何正整数(包括1本身)都是互质。

正整数的因数分解可将正整数表示为一连串的质因子相乘,质因子如重复可以用指数表示。

根据算术基本定理,任何正整数皆有独一无二的质因子分解式。只有一个质因子的正整数为质数。
请在这里输入引用内容
每个合数都可以写成几个质数(也可称为素数)相乘的形式,这几个质数就都叫做这个合数的质因数。如果一个质数是某个数的因数,那么就说这个质数是这个数的质因数;而这个因数一定是一个质数。        

具体请查看什么是质因数,质因数(素因数或质因子)在数论里是指能整除给定正整数的质数-CSDN博客文章浏览阅读3.4k次,点赞2次,收藏4次。每个合数都可以写成几个质数(也可称为素数)相乘的形式,这几个质数就都叫做这个合数的质因数。如果一个质数是某个数的因数,那么就说这个质数是这个数的质因数;16=2×2×2×2,2就是16的质因数,把一个合数写成几个质数相乘的形式表示,这也是分解质因数。正整数的因数分解可将正整数表示为一连串的质因子相乘,质因子如重复可以用指数表示。什么是质因数,质因数(素因数或质因子)在数论里是指能整除给定正整数的质数。质因数(素因数或质因子)在数论里是指能整除给定正整数的质数。只有一个质因子的正整数为质数。......https://blog.csdn.net/Hodors/article/details/126038749#:~:text=%E8%B4%A8%E5%9B%A0%E6%95%B0%EF%BC%88%E7%B4%A0%E5%9B%A0%E6%95%B0%E6%88%96%E8%B4%A8%E5%9B%A0%E5%AD%90%EF%BC%89%E5%9C%A8%E6%95%B0%E8%AE%BA%E9%87%8C%E6%98%AF%E6%8C%87%E8%83%BD%E6%95%B4%E9%99%A4%E7%BB%99%E5%AE%9A%E6%AD%A3%E6%95%B4%E6%95%B0%E7%9A%84%E8%B4%A8%E6%95%B0%E3%80%82%20%E9%99%A4%E4%BA%861%E4%BB%A5%E5%A4%96%EF%BC%8C%E4%B8%A4%E4%B8%AA%E6%B2%A1%E6%9C%89%E5%85%B6%E4%BB%96%E5%85%B1%E5%90%8C%E8%B4%A8%E5%9B%A0%E5%AD%90%E7%9A%84%E6%AD%A3%E6%95%B4%E6%95%B0%E7%A7%B0%E4%B8%BA%E4%BA%92%E8%B4%A8%E3%80%82,%E5%9B%A0%E4%B8%BA1%E6%B2%A1%E6%9C%89%E8%B4%A8%E5%9B%A0%E5%AD%90%EF%BC%8C1%E4%B8%8E%E4%BB%BB%E4%BD%95%E6%AD%A3%E6%95%B4%E6%95%B0%EF%BC%88%E5%8C%85%E6%8B%AC1%E6%9C%AC%E8%BA%AB%EF%BC%89%E9%83%BD%E6%98%AF%E4%BA%92%E8%B4%A8%E3%80%82%20%E6%AD%A3%E6%95%B4%E6%95%B0%E7%9A%84%E5%9B%A0%E6%95%B0%E5%88%86%E8%A7%A3%E5%8F%AF%E5%B0%86%E6%AD%A3%E6%95%B4%E6%95%B0%E8%A1%A8%E7%A4%BA%E4%B8%BA%E4%B8%80%E8%BF%9E%E4%B8%B2%E7%9A%84%E8%B4%A8%E5%9B%A0%E5%AD%90%E7%9B%B8%E4%B9%98%EF%BC%8C%E8%B4%A8%E5%9B%A0%E5%AD%90%E5%A6%82%E9%87%8D%E5%A4%8D%E5%8F%AF%E4%BB%A5%E7%94%A8%E6%8C%87%E6%95%B0%E8%A1%A8%E7%A4%BA%E3%80%82

完结撒花

        可以看出,这个相对来说很基础,之所以记录下来是因为对【后面的“ + 1 ”必须有】的思考,为什么需要 + 1 呢?其实很简单,不加就会把平方根下的这个因数给遗漏掉,导致把一个🈴数误判为质数,这是不允许的。 

### 回答1: #include <stdio.h> int main() { int n, i; printf("输入一个正整: "); scanf("%d",&n); printf("分解质因数: "); for(i=2; i<=n; i++) { while(n%i == 0) { printf("%d ",i); n=n/i; } } printf("\n"); return 0; } ### 回答2: 要实现一个运行速度最快的分解质因数算法,可以使用Pollard Rho算法。这是一个基于随机性的质因数分解算法,其主要思想是通过不断迭代生成一个序列,其中的元素可能是合,然后使用辗转相除法来判断是否找到一个质因数。 下面是使用C代码实现的简化版本: ``` #include <stdio.h> long long gcd(long long a, long long b) { if (b == 0) { return a; } else { return gcd(b, a % b); } } long long pollardRho(long long n) { long long x = 2, y = 2, d = 1; while (d == 1) { x = (x * x + 1) % n; y = (y * y + 1) % n; y = (y * y + 1) % n; d = gcd((x - y + n) % n, n); } return d; } int main() { long long n; printf("请输入一个正整:"); scanf("%lld", &n); printf("%lld的一个质因数是:%lld\n", n, pollardRho(n)); return 0; } ``` 该代码通过解随机迭代序列的非平凡最大公约找到一个质因数。与传统的试除法相比,Pollard Rho算法在较大的上运行速度更快。在实际使用时,可以进一步改进代码以提高效率,并处理特殊情况。 ### 回答3: 要编写一个运行速度最快的分解质因数算法,可以采用试除法的优化形式,又称为Pollard's rho算法。 首先,我们需要写一个用于检测一个是否为素的函。可以使用试除法,从2到sqrt(n)逐个检查是否有因。如果找到一个,说明n不是素;如果没有找到,说明n是素。 接下来,我们可以使用Pollard's rho算法来分解质因数。这个算法的思想是利用了环的周期性来找到质因数。 具体步骤如下: 1. 定义一个f(x),表示f(x) = x^2 + 1。 2. 初始化x = 2和y = 2,计算f(x)和f(f(y))。 3. 利用欧几里得算法计算f(x)和f(f(y))的差值d。 4. 如果d是一个质数,则d即为n的一个质因数。 5. 如果d是合,重复步骤2-4直到找到一个质因数。 通过不断重复步骤2-4,我们可以找到n的一个质因数。然后可以递归地对这个质因数进行分解,直到无法再分解为止。 通过这种方式,可以得到一个快速质因数分解算法。当然,实现中还可以对代码进行优化,例如可以用位运算代替乘法和除法操作,以提高运行速度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值