• 素数及筛法


    素数简介

    素数(prime number)又称质数,有无限个。
    素数定义为在大于1的自然数中,除了1和它本身以外不再有其他因数。

    接下来介绍几种判断素数的方法:

    问法1:给定一个数n,判断n是不是素数

    一、暴力枚举

    枚举2~n-1分别当做除数,判断是否能整除,如果某个数能把n整除,那么就说明n不是素数,如果所有都不能整除,那么n就是素数。
    注:n=1或n=2时需要特判

    详见代码:

    bool work(int n)
    {
    	if(n==1)return false;
    	if(n==2)return true;
    	for(int i=2;i<=n-1;i++)
    	{
    		if(n%i==0)return false;
    	}
    	return true;
    }
    

    然而这样会很慢......

    二、优化过的暴力算法

    由于n至少会有一个约数在sqrt(n)中,所以我们可以直接枚举从2~sqrt(n),这样便会快不少。

    详见代码:

    bool work(int n)
    {
    	if(n==1)return false;
    	if(n==2)return true;
    	for(int i=2;i*i<=n;i++)//这里也可以写成i<=sqrt(n)
    	{
    		if(n%i==0)return false;
    	}
    	return true;
    }
    

    以上所说的算法只是用来判断单个素数的,但是若是要求1~n之间的素数该怎么办呢?

    还是暴力?
    不!
    要用到一个名叫“筛法”的东东

    三、埃氏筛法

    由于我们知道,2的任何倍数都不可能是素数,3的任何倍数不可能是素数,5的任何倍数不可能是素数......
    所以我们可以把素数的倍数全部筛掉。
    详见代码:

    /*
    vis用来判断有没有被筛掉,
    prime用来存储素数
    cnt代表素数总数
    */
    for(int i=2;i<=n;i++)
    {
    	if(vis[i]==1)continue;
    	prime[++cnt]=i;
    	for(int j=1;j*i<=n;j++)//筛掉素数的所有倍数
    	{
    		vis[j*i]=1;
    	}
    }
    

    但是以12为例
    12是2的倍数,被筛
    12是3的倍数,被筛++
    所以事实证明会有一些数被筛好多次
    那要怎么做到每个数只筛一次的线性复杂度呢?

    四、线性筛

    线性筛,又称欧拉筛
    欧拉筛法的基本思想 :在埃氏筛法的基础上,让每个合数只被它的最小质因子筛选一次,以达到不重复的目的。

    /*
    vis用来判断有没有被筛掉,
    prime用来存储素数
    cnt代表素数总数
    */
    for(int i=2;i<=n;i++)
    {
    	if(!vis[i])prime[++cnt]=i;
    	for(int j=1;j<=cnt&&i*prime[j]<=n;j++)
    	{
    		vis[i*prime[j]]=1;
    		if(i%prime[j]==0)break;
    	}
    }
    

    以上就是素数判断及筛法的总结,谢谢观看

    参考文献资料:
    https://www.baidu.com
    https://blog.csdn.net/qq_39763472/article/details/82428602

    最后打个小广告:
    https://www.luogu.org/blog/hulean0319/Game-ZMXY

  • 相关阅读:
    BFC——块级格式化上下文
    深入浅出——float
    NodeJS 学习记录
    JavaScript高级程序设计 第六章 面向对象程序设计
    软件项目管理课感想
    第八周PSP 新折线图和饼图 个人时间管理
    第七周PSP 新折线图和饼图 个人时间管理
    Alpha、伪Beta 发布个人感想与体会
    ”单元测试“理解与感悟
    编程
  • 原文地址:https://www.cnblogs.com/hulean/p/10799277.html
Copyright © 2020-2023  润新知