判断质数与分解质因数基础算法与优化。

文章介绍了质数的定义,通过试除法和枚举优化判断质数的方法,并详细阐述了如何进行分解质因数,包括优化的策略,即只枚举小于平方根的质数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

素数(质数)

定义:只有1和它本身作为约数(因数的数)。

合数

不是质数的自然数是合数。(就是除了他自己本身还有别的约数)

质因数

定义:一个数即是质数,也是某数x的因数,叫做x的质因数。

判断质数
试除法
  • 循环枚举x的约数,如果最后只能被他自己除掉,那么就是质数,算法的复杂度是o(n)
bool isPrime(int x){
    if(x<2) return false;
    for(int i=2;i<x;i++){
        if(x%i==0)return false;
    }
    return true;
}
枚举优化

我们可以注意到,约数都是成对出现的,也就是说,如果一个数n的约数是d,那么n/d也是n的约数。所以实际上我们可以只枚举每一对约数中的一个即可,优化后的算法复杂度大约是根号n,优化后的代码是

bool isPrime(int x){
    if(x<2) return false;
    for(int i=2;i<=x/i;i++){//只要比较小的那个约数,这里比较的不是数量,是两约数的大小关系。
        if(x%i==0)return false;
    }
    return true;
}
分解质因数

在数学上我们用短除法来分解一个数的质因数。如下图所示

image.png
什么意思呢?就是从最小的质数开始去除这个数,直到除出来的数是1(上面的图还有最后一步),分解就结束。
在计算机也是枚举质数来分解质因数

void divide(int x){
    for(int i=2;i<=x;i++){//等于号是为了除以本身
        int res=0;
        if(x%i==0){//满足该条件的i一定是一个质数
            while(x%i==0){
                x/=i;
                res++;//res是指数,i是底数
            }
            printf("%d %d\n",i,res);
        }
    }
}

也许会有人有一个疑问,明明枚举的是质数,怎么变成了枚举所有数呢?会不会有合数被枚举了出来呢?
答案是不会的。因为当我们枚举到i且if的条件成立时的时候,说明前面的2->i-1都是不能被现在的x整除的(是现在的x,x一直在变化,联系在数学求质因数时的短除法),那么又因为x是i的倍数,那么我们知道前面的2->i-1也是不能被i整除的,那么我们就知道i一定是质数。每一个i都是质数,所以当然也就不会有合数被枚举了。

优化分解质因数的方法

首先我们要知道。

  • 一个合数x最多只包含一个大于sqrt(x)的质因子(如果有两个那么乘起来就会大于x)。
    所以我们就可以先枚举小于sqrt(x)的数(质数),如果最后剩下的x仍然大于1,那么再去单独处理输出。
void divide(int x){
    for(int i=2;i<=x/i;i++){//这里是需要x的,因为我们是在枚举质因数,有可能自己本身也是需要一次的
        int res=0;
        if(x%i==0){
            while(x%i==0){
                x/=i;
                res++;
            }
            printf("%d %d\n",i,res);
        }
    }
    if(x>1) printf("%d 1\n",x);
}

-----acwing跟y总学习的笔记。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

谢林365

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值