数论1:简单素数判断

假设我们要判断的数为n,则有以下讨论:

素数只能被1和本身整除,那么试除\(O(n)\)

n非素数,其约数必成对出现,如3和12/3=4都是12的约数,3和9/3=3都是9的约数(这里的成对可以相同),那么我们只需考虑\(\le \sqrt n\)的数,得\(O(\sqrt n)\)

素数可以被分为两类,偶素数和奇素数。偶素数只有2,所以我们在遍历之前单独判断n是否被2整除,并将循环步长增置2,得\(O(\frac{\sqrt n}{2})\)

bool isprime(int n)
{
    if(n < 2) return 0;
    if(n == 2) return 1;
    if(n % 2 == 0) return 0;

    int lim = sqrt(n);
    for(int i = 3; i <= lim; i += 2)
        if(n % i == 0) return 0;
    return 1;
}

奇素数可以通过产生所有奇数的表达式产生,比如:\(4k+1\)\(4k+3\)能生成所有的奇数,所以这里的步长可为4,得\(O(\frac{\sqrt n}{4})\)

bool isprime(int n)
{
    if(n < 2) return 0;
    if(n == 2) return 1;
    if(n % 2 == 0) return 0;

    int lim = sqrt(n);
    for(int i = 3; i <= lim; i += 4)
        if(n % i == 0) return 0;
    return 1;
}

提前先判断一部分奇数,减少后序循环中所需工作。比如\(6k+1\)\(6k+3\)\(6k+5\)
可生成所有奇数,提前判断3,则可令步长为6,得\(O(\frac{\sqrt n}{6})\)

bool isprime(int n)
{
    if(n < 2) return 0;
    if(n < 4) return 1;
    if(n % 2 == 0 || n % 3 == 0) return 0;
    if(n < 9) return 1;

    int lim = sqrt(n);
    // i+2是因为6k+5与6k-1同余,而6k-1与6k+1差2,所以+2
    for(int i = 5; i <= lim; i += 6)
        if(n % i == 0 || n % (i+2) == 0) return 0;
    return 1;
}

n若为合数,必能通过唯一形式的素数连乘形式表示(算术基本定理)
所以在上述方法中,不需考虑所以\(\le \sqrt n\)的数,仅考虑\(\le \sqrt n\)的素数即可,这里的时间复杂度可达\(O(\lg \sqrt n)\)

但是,如何生成素数呢?

转载于:https://www.cnblogs.com/sequix/p/8524767.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值