素数 判断一个数是否是素数+素数筛法

一、定义:

    质数又称素数。一个大于1的自然数,除了1和它自身外,不能被其他自然数整除的数叫做质数;否则称为合数

ps:不大于n的素数的个数为:n/ln(n);(n/Math.log(n))

二、性质

质数具有许多独特的性质:
(1)质数p的约数只有两个:1和p。
(2)初等数学基本定理:任一大于1的自然数,要么本身是质数,要么可以分解为几个质数之积,且这种分解是唯一的。
(3)质数的个数是 无限的。
(4)质数的个数公式
是不减函数。
(5)若n为 正整数,在
之间至少有一个质数。
(6)若n为大于或等于2的正整数,在n到
之间至少有一个质数。
(7)若质数p为不超过n(
)的最大质数,则
(8)所有大于10的质数中,个位数只有1,3,7,9。

三、编程:

基本判断思路:

在一般领域,对正整数n,如果用2到
之间的所有整数去除,均无法整除,则n为质数。
质数大于等于2 不能被它本身和1以外的数整除

代码:

 
from  math  import  sqrt
def  is_prime(n):
     if  = =  1 :
         return  False
     for  in  range ( 2 int (sqrt(n)) + 1 ):
         if  %  = =  0 :
             return  False
     return  True
Java代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
1 .  
  public  static  boolean  testIsPrime2( int  n){
        if  (n <=  3 ) {
             return  n >  1 ;
         }
        
        for ( int  i= 2 ;i<n;i++){
            if (n%i ==  0 )
                return  false ;
        }
        return  true ;
    }
 
/*优化后*/
 public static boolean testIsPrime3(int n){
       if (n <= 3) {
            return n > 1;
        }
        
       for(int i=2;i<=Math.sqrt(n);i++){
           if(n%i == 0)
               return false;
       }
       return true;
   }
 
    
    
 
 
2 .
public  class  Prime {
     public  static  void  main(String[] args) {
         int  a =  17 //判断17是不是质数
         int  c =  0 ;
         for  ( int  b =  2 ; b < a; b++) {
             if  (a % b !=  0 ) {
                 c++;
             }
         }
         if  (c == a -  2 ) {
             System.out.println(a +  "是质数" );
         else  {
             System.out.println(a +  "不是质数" );
         }
     }
}

C#代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
using  System;
  namespace  计算质数
 {
     class  Program
    {
         static  void  Main( string [] args)
        {
             for  ( int  i = 2,j=1; i < 2100000000&&j<=1000; i++) //输出21亿内的所有质数,j控制只输出1000个。
            {
                 if  (st(i))
                {
                    Console.WriteLine( "{0,-10}{1}" ,j,i);
                    j++;
                }
            }
        }
         static  bool  st( int  n) //判断一个数n是否为质数
        {
             int  m = ( int )Math.Sqrt(n);
             for ( int  i=2;i<=m;i++)
             {
                 if (n%i==0 && i!=n)
                     return  false ;
           } 
             return  true ;
        }
    }
 }
 
C代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <stdio.h>
#include <windows.h>
int  main()
{
     double  x,y,i;
     int  a,b;
     x = 3.0;
     do {
         i = 2.0;
         do {
             y = x / i;
             a = ( int )y;
             if (y != a) //用于判断是否为整数
             {
                 if (i == x - 1)
                 {
                     b = ( int )x;
                     printf ( "%d\n" ,b);
                 }
             }
             i++;
         } while (y != a);
         x++;
     } while (x <= 10000.0); //3到10000的素数
     system ( "pause" ); //防止闪退
     return  0;
}
C/C++代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include<iostream>
#include<algorithm>
#include<cmath>
using  namespace  std;
const  long  long  size=100000; //修改size的数值以改变最终输出的大小
 
long  long  zhishu[size/2];
void  work(){ //主要程序
     zhishu[1]=2;
     long  long  k=2;
     for ( long  long  i=3;i<=size;i++){ //枚举每个数
         bool  ok=1;
         for ( long  long  j=1;j<k;j++){ //枚举已经得到的质数
             if (i%zhishu[j]==0){
                 ok=!ok;
                 break ;
             }
         }
         if (ok){
             zhishu[k]=i;
             cout<< "count" <<k<< ' ' <<i<<endl;
             k++;
         }
     }
}
 
 
int  main(){
     freopen ( "zhishu.out" , "w" ,stdout);
     cout<< "count1 2" <<endl;
     work();
     return  0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
bool  isPrime(unsigned  long  n) {
     if  (n <= 3) {
         return  n > 1;
     else  if  (n % 2 == 0 || n % 3 == 0) {
         return  false ;
     else  {
         for  (unsigned  short  i = 5; i * i <= n; i += 6) {
             if  (n % i == 0 || n % (i + 2) == 0) {
                 return  false ;
             }
         }
         return  true ;
     }
}
Javascript代码:
1
2
3
4
5
6
7
8
9
function  isPrime(n) {
     if  (n <= 3) {  return  n > 1; }
     if  (n % 2 == 0 || n % 3 == 0) {  return  false ; }
 
     for  ( var   i = 5; i * i <= n; i += 6) {
         if  (n % i == 0 || n % (i + 2) == 0) {  return  false ; }
     }
     return  true ;
}
四、素数筛法:
筛素数法可以比枚举法节约极大量的时间(定n为所求最大值,m为≤n的质数个数,那么枚举需要O(n^2)的时间复杂度,而筛素数法为O(m*n),显然m<<n,所以时间效率有很大提升。)。如1000000的数据范围,用筛素数法可在2s内解决。
思路:建立一个bool型数组M, 若已知一个数M[k]是质数,那么其i(i为正整数)倍M[k*i]必然为合数,可将其去除。


//c++代码 all rights reserve.
#include<iostream>
#include<cstdio>
#include<algorithm>
using  namespace  std;
const  long  long  size=1000000; //修改此值以改变要求到的最大值
bool  zhishu[size+5]={ false };
int  main(){
     freopen ( "zhishu.out" , "w" ,stdout); //输出答案至“筛质数(shaizhishu).exe”所在文件夹内
     zhishu[2]= true ;
     for ( long  long  i=3;i<=size;i+=2)zhishu[i]= true ; //所有奇数标为true,偶数为false
     for ( long  long  i=3;i<=size;i++){
         if (zhishu[i]){ //如果i是质数
             int  cnt=2;
             while (cnt*i<=size){ //把i的倍数标为false(因为它们是合数)
                 zhishu[cnt*i]= false ;
                 cnt++;
             }
         }
     }
     int  cnt=1;
     for ( int  i=2;i<=size;i++){ //全部遍历一遍
         if (zhishu[i]){ //如果仍然标记为true(是质数)则输出
             cout<<cnt<< ' ' <<i<<endl;
             cnt++;
         }
     }
     return  0;
}
/*
样例输出结果,第一个数是个数,第二个是第几个质数
 
1 2
2 3
3 5
4 7
5 11
6 13
7 17
8 19
9 23
10 29
11 31
12 37
13 41
14 43
15 47
16 53
17 59
18 61
19 67
20 71
21 73
22 79
23 83
24 89
25 97
*/
素数筛法的Java实现,如下:


public  class  SOE {
 
     public  static  int  calPrime( int  n){
         if (n<= 1 ){
             return  0 ;
         }
         byte [] origin =  new  byte [n+ 1 ];
         int  count =  0 ;
         for ( int  i= 2 ;i<n+ 1 ;i++){
             if (origin[i] ==  0 ){
                 count++;
                 int  k =  2 ;
                 while (i*k<=n){
                     origin[i*k] =  1
                    k++;  
                 }
             } else {
                 continue ;
             }
         }
         return  count;
     }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值