素数判断方法总结

9 篇文章 0 订阅
9 篇文章 0 订阅

今天想总结一下素数的几种求法
暴力方法:
最简单的方法就是从2开始循环到n,如果没有一个数能被n整除就是素数

#include<stdio.h>
int isPrime(int n) {
    for(int i=2; i<n; i++) {
        if(n%i == 0)
            return 0 ;
    }
    return 1 ;
}
int main() {
    int x ;
    scanf("%d", &x) ;
    if(isPrime(x))
        printf("YES\n") ;
    else
        printf("NO\n") ;
    return 0 ;
}

这个方法是最简单粗暴的,但是也是效率最低的需要循环到n-1,可以进行一点改进,循环的判断条件只需要到n/2+1就可以了

int isPrime(int n) {
    for(int i=2; i<n/2+1; i++) {
        if(n%i == 0)
            return 0 ;
    }
    return 1 ;
}

这样循环的次数还是不够少,其实只需要判断到根号n次就行,一般来说可以使用sqrt(n)来求根号n,我们还可以用 i*i<n来实现

int isPrime(int n) {
    for(int i=2; i*i<n; i++) {
        if(n%i == 0)
            return 0 ;
    }
    return 1 ;
}

其实还可以继续优化这个方法,因为除了2以外的所有偶数都不可能是素数,所以我们只需要判断奇数就行

bool isPrime(int n) {
    if(n%2==0 && n!=2)  //除了2以外的所有偶数都不是素数
        return false ;
    else if(n == 2)
        return true ;
    for(int i=3; i*i<n; i+=2) {     //3-根号n内没有一个数能被n整除就是素数
        if(n%i == 0)
            return false ;
    }
    return true ;
}

这是我目前能想到用暴力的方法最优的样子,如果还有可以优化的地方欢迎指教

埃氏筛:
这个方法是通过打表找出指定范围内所有的素数,当数字范围小的时候用暴力没问题但只要范围太大就用不了了,就可以用这个方法
原理:从2开始循环,将2存入素数表中,把2所有的倍数都舍去,然后对3进行相同的操作,一直这样循环到头


#include<cstdio>
int isPrime[100000] ;       //记录该点是否是素数
int prime[100000] ;         //存素数
int main() {
    int count = 0 ;         //记录共有几个素数
    for(int i=2; i<100000; i++) {
        if(isPrime[i] == 0) {   //从2 开始将2的所有倍数除去然后是3的倍数4的倍数…………
            prime[count++] = i ;    //将素数存入
            for(int j=i*i; j<100000; j+=i)  
                isPrime[j] = 1 ;
        }
    }
    for(int i=0; i<count; i++) {
        printf("%d ",prime[i]) ;
        if(i%10 == 0)
            printf("\n") ;
    }
    return 0 ;
}

第二层for循环中j 从 i * i 而不是从 i + i开始,因为 i*(2~ i-1)在 2~i-1时都已经被筛去,所以从i * i开始
这个方法有个缺点就是会重复多次筛去一个点,于是就有了下一个方法

欧拉筛:
这个方法是在埃氏筛的基础上做了一点改进,原理是把一个合数(6=2*3)通过它的最小质因子筛去

#include<cstdio>
int isPrime[100000] ;
int prime[100000] ;
int main() {
    int count = 0 ;
    for(int i=2; i<100000; i++) {
        if(isPrime[i] == 0)
            prime[count++] = i ;
        for(int j=0; j<count&&i*prime[j]<100000; j++) {   //找出由i和已得到的素数相乘得到的数
            isPrime[i*prime[j]] = 1 ;   //将由i和最小质因数相乘得到的数排除,
            if(i%prime[j] == 0)     //如果i能被已经存过的素数整除,说明在之前就由其他的i和最小质因数相乘过,不用重复查
                break ;
        }
    }
    for(int i=0; i<count; i++) {
        printf("%d ",prime[i]) ;
        if(i%10 == 0)
            printf("\n") ;
    }
    return 0 ;
}

总结:
通过写这个求素数的不同方法,从低效的逐渐提高效率,也反应了学习编程一年的一些想法上的进步,这样看上去还是比较开心的。所以说考虑一个问题还是要多研究多考虑深一些,不断优化自己的代码

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
判断素数的函数可以使用方法二:从2到(根号n)判断是否有因数。你可以使用以下C++代码实现: ```cpp #include<iostream> #include<cmath> using namespace std; bool isPrime(int n){ if(n == 2 || n == 3) return true; else{ for(int i = 2; i <= sqrt(n); i++){ if(n % i == 0) return false; } return true; } } ``` 这个函数接受一个整数n作为参数,并返回一个布尔值,用于判断n是否为素数。你可以在函数中使用for循环从2到根号n来判断n是否有因数,如果找到了一个因数,说明n不是素数,返回false;如果循环结束后都没有找到因数,说明n是素数,返回true。这样你就可以用这个函数来判断一个数是否为素数了。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [C/C++语言:判断是否是素数](https://blog.csdn.net/weixin_45580017/article/details/123881257)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [素数的几种判断方法总结(含C++代码)](https://blog.csdn.net/alazyperson/article/details/104083695)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值