zoukankan      html  css  js  c++  java
  • 素数问题(转)

    素数问题(转)
    参考文:http://blog.csdn.net/hechenghai/article/details/6733907

    定义:除了1和其本身,没有其他约数的数。
    算法:用n分别试除2到sqrt(n)的数,如果中间有一个能整除,即为合数,否则即为素数。

    著名的素数筛选法:
    公元前300多年,学者埃拉托色尼提出了一种方法,他在一张纸上写上自然数列的数字,把它贴在一个柜子上,然后把其中的合数一个一个地挖去。得到一个有许多小孔的像筛子一样的东西,所有的合数都好像被筛子筛去了一样。埃拉托色尼是怎样筛法呢?他若造一张1到50的素数表,首先写上1到50的所有自然数,然后先划去1,把2留下,再划去其他所有2的倍数,把3留下。再划去其他所有3的倍数,把5留下。又划去其他所有5的倍数……以此类推,可以得到50以内的所有素数。
    按照埃拉托色尼的筛法,会不会划到最后都是合数呢?也就是素数的个数是不是有限的呢? 约公元前275年,希腊著名的数学家欧几里德用巧妙的方法证明了素数是无限的。

    C语言算法
    //求1000以内所有素数,用筛选法

    #include <stdlib.h>
    #include <stdio.h>
    #include <math.h>
    #define SIZE 1000
     
    int main(int argc, char *argv[])
    {
      int sign[SIZE];
      int i, j;
      for (i = 0; i < SIZE; i++){
          sign[i] = 1;
      }
      
      for (i = 2; i <= sqrt((double)SIZE); i++){
          if (sign[i]){
              for (j = 2; j <= SIZE / i; j++){
                  sign[i*j]=0;
              }
          }
      }
      
       for (i = 2; i < SIZE; i++){
          if(sign[i])
              printf("%d,",i);
      }
      system("PAUSE");
      return 0;
    }

    素数判定方法:
    1.遍历2以上N的平方根以下的每一个整数,是不是能整除N;(这是最基本的方法)

    C语言描述:

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

    2.遍历2以上N的平方根以下的每一个素数,是不是能整除N;(这个方法是上面方法的改进,但要求N平方根以下的素数已全部知道)

    但以上算法都不适合长整数的素数判断,通常会采用概率算法。(这里就不贴概率算法了。)

    bool is_prime(int n)//判断n是否为素数,是素数返回1
    {
        int i;
        bool flag = 1;
        for(i = 2; i <= sqrt(n); i++)
        {
            if(n % i == 0){
                flag = 0;
                break;
            }
        }
        return flag;
    }

    小范围内筛素数(数据不太大):

    #define Max 1000
    int Prime[500];
    int q;
    void get_prime()
    {
        q = -1;
        Prime[++q] = 2;
        Prime[1] = 3;
        int i;
        for(i = 5; i <= Max; i++){
            for(j = 0;Prime[j]*Prime[j] <= i &&i%Prime[j] != 0; j++);
            if(Prime[j]*Prime[j] > i)Prime[++q] = i;
        }
    } 

    大范围内筛素数的普通筛法(很慢):

    #define Max 1000000
    int Prime[500000];
    bool IsPrime[Max] = {1};
    int q;
    void get_prime()
    {
        q = -1;
        int i,j;
        for(i = 2; i*i < Max; i++){
            if(IsPrime[i] == 1){
                for(j = i+i; j < Max; j += i){
                    IsPrime[j] = 0;
                }
            }
        }
        for(i = 2; i < Max; i++){
            if(IsPrime[i] == 1)
            Prime[++q] = i;
        }
    } 

    大范围内素数的线性筛法(比普通筛法更快)

    #define Max 1000000
    int Prime[500000];
    bool IsPrime[Max] ;
    int q;
    void get_prime()
    {
        memset(IsPrime,true,sizeof(IsPrime));//将数组初始化为true
        q = -1;
        int i,j;
        for(i = 2; i < Max; i++){
            if(IsPrime[i] == 1)
                Prime[++q] = i;
            for(j = 0;j <= q && Prime[j] * i < Max; j++){
                    IsPrime[Prime[j] * i] = 0;
                    if(i % Prime[j] == 0)break;
            }
        }
    } 

    求某一区间(a,b)内的素数

    有时候我们碰到的问题是要求求出a b间的素数,而a又比较大,这种情况下就可以用这种方法实现(a>2)
    注意:要先通过以上几种方法求出2到sqrt(a的最大取值)范围内的素数存入Prime[].

    int prime[500000];
    bool isprime[1000000];
    int qt;
    void get_prime1(int a,int b)
    {
        int i,j,k;
        for(i = 0; i <= b - a; i++)
        isprime[i] = 1;
        for(i = 0; Prime[i]*Prime[i] <= b && i <= q;i++){
                k = a/Prime[i];
                if (k*Prime[i] < a) k++;
                if (k <= 1) k++;
                while(k*Prime[i] <= b){
                    isprime[k*Prime[i] - a] = 0;
                    k++;
                }
        }
        qt = -1;
        for(i = 0; i <= b - a; i++)
        {
            if(isprime[i] == 1)
            prime[++qt] = i + a;
        }
    }

  • 相关阅读:
    前端TypeScript编写的代码发布后怎么在浏览器中调试
    oracle中的执行计划
    oracle中的物化视图
    oracle中的exists 和not exists 用法
    Oracle中的索引详解
    Oracle中动态SQL拼接
    oracle 中sql优化的几种方法
    oracle中常用函数大全
    Oracle中游标的用法
    oracle中表分区的实现
  • 原文地址:https://www.cnblogs.com/lionfight/p/2512269.html
Copyright © 2011-2022 走看看