练习筛法遍历素数(Java)

Posted senwren

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了练习筛法遍历素数(Java)相关的知识,希望对你有一定的参考价值。

 初学Java,学到流程控制的循环,有个练习题是暴力遍历素数。

因为看过av32186751,知道有个筛法,就想试试。

 又受到线性筛法(一)--素数筛法(一) - nerd呱呱 - 博客园中,的这段启发,就有了下面的代码。

 

引用文字:

我们先定义一个数组来存100000以内数是否的素数,下标表示数,数组的值1表示是素数,0表示不是素数。

我们可以换个角度思考,要找素数,其实只要把不是素数的排除就可以了。

 

代码:

  1 import java.util.Scanner;
  2 /**
  3  * ShaiFa_Prime__Basic
  4  * @author HmLy.0000
  5  * * * * * * * * * * * * * 
  6  */
  7 public class ShaiFa_Prime__Basic {
  8 
  9     /**
 10      * 这边,直接用i 来表示"thisNumber[i]" ... 
 11      */
 12     public static void main(String[] args) {
 13         System.out.println();
 14         Scanner scn = new Scanner(System.in);
 15         System.out.println("# 【这是个筛法遍历素数的工具】");
 16 
 17         System.out.println("# --> 目前还不能输入同一个数。");
 18         System.out.println("# ");
 19         System.out.println("# ==== -- ==== -- ==== -- ====  ");
 20         System.out.println("# 请指定遍历素数区间范围 : ");
 21         System.out.println("# ---- --- --- ---- --- -- ---- -- -");
 22 
 23 
 24 
 25         boolean[] isPrime_AHA;
 26         int numberArr_i_OP, numberArr_i_ED;
 27 
 28 
 29 
 30 
 31 
 32         while (true) {
 33             System.out.print  ("# 指定区间边界<1>, 最少是 2    :  | ");
 34             numberArr_i_OP = scn.nextInt();
 35             if (numberArr_i_OP >= 2) {
 36                 break;
 37             } else {
 38                 System.out.println("# [ERR!!] - === 您输入的值非法,请重新输入!!====");
 39             }//if-else_to_break
 40         }//whileTrue
 41 
 42 
 43 
 44         while (true) {
 45             System.out.print  ("# 指定区间边界<1>, 最少是 2    :  | ");
 46             numberArr_i_ED = scn.nextInt();
 47             if (numberArr_i_ED >= 2) {
 48                 break;
 49             } else {
 50                 System.out.println("# [ERR!!] - === 您输入的值非法,请重新输入!!====");
 51             }//if-else_to_break
 52         }//whileTrue
 53 
 54 
 55 
 56 
 57 
 58         if (numberArr_i_ED < numberArr_i_OP){
 59             int temp = numberArr_i_ED;
 60             numberArr_i_ED = numberArr_i_OP;
 61             numberArr_i_OP = temp;
 62         }//交换位置
 63 
 64 
 65 
 66 
 67 
 68 
 69 
 70 
 71         //int largePrim = (numberArr_ED - numberArr_OP + 1);
 72         isPrime_AHA = new boolean[numberArr_i_ED + 1];
 73 
 74 
 75         for (int i = 0; i <= numberArr_i_ED; i++) {
 76             isPrime_AHA[i] = true;
 77         }
 78 
 79         isPrime_AHA[0]= false;
 80         isPrime_AHA[1]= false;//先不想办法省掉它俩。。
 81 
 82         int nnn_i__tst;
 83         for (int i = 2; i <= numberArr_i_ED; i++) {
 84 
 85             if(isPrime_AHA[i]){
 86                 for (nnn_i__tst = i*2; nnn_i__tst <= numberArr_i_ED; nnn_i__tst++) {
 87                     if(nnn_i__tst% i== 0){
 88                         isPrime_AHA[nnn_i__tst] = false;
 89                     }
 90                 }//检查大于2的数是否是其倍数,是,就false。从2 的两倍开始检查 - 因为其前面的必定不是倍数。。。。
 91             }//对所有还没false的进行操作。
 92         }//不光检查2。所有还没false的都得检查。
 93 
 94 
 95 
 96 
 97 
 98         //打印
 99         System.out.println("# ---- --- --- ---- --- -- ---- -- -");
100         System.out.println("# 区间为                       :  |["+ numberArr_i_OP +", "+ numberArr_i_ED +"]");
101         System.out.println("# 区间长度                     :  |["+ (numberArr_i_ED +1 - numberArr_i_OP) +"]");
102         System.out.println("#   ----   ----      ----   ----  | ");
103         int primeCunt = 0;
104         for (int i = numberArr_i_OP; i <= numberArr_i_ED; i++) {
105             if (isPrime_AHA[i]) {
106                 primeCunt++;
107             }
108         }//数数
109         System.out.println("# 区间中素数个数               :  | "+ primeCunt);
110         System.out.println("# -- -                           - ---- --");
111 
112 
113         for (int i = numberArr_i_OP; i <= numberArr_i_ED; i++) {
114             if (isPrime_AHA[i]) {
115                 System.out.println("# 区间中的素数                 :  | "+ i);
116             }
117         }//输出
118         System.out.println("# ---- --- --- ---- --- -- ---- -- -");
119     }//main
120 }
121 /**
122  * 受到了查到的筛法的启发。
123  * * * * * * * * * * * * * 
124  * 先前尝试再来个数组,就不用让 i 为 0 和 1
125  * 的部分被白费,但直接整晕了... 上面这个先简单来,成功了。
126  */

 为了这个专门预习了数组。

一开始独立写代码,想在开始就不让程序浪费一开始的0和1两个下标,就又弄了一个数组又定义了一堆新变量,然后自己也晕在里面了。。。索性就不管这个,然后就成了。

- - - - - - 

对了,一开始的时候弄得那个全是bug的代码似乎还一口气加上了指定遍历开头的功能……

这个的话,是从2开始遍历,只是取值可以设定区间而已,区间只是帮助截取显示的部分,选择小区间并不见得就会减少程序运算量。。。。

- - - - - - 

而且,遍历下标倍数的时候上面的代码也弄复杂了。

甭判断这个 % 那个是不是 0 ,直接从 2 到 n 操作一遍 isPrime[i*j] = false ,就成了。。。。

以上是关于练习筛法遍历素数(Java)的主要内容,如果未能解决你的问题,请参考以下文章

代码模板——素数筛法

埃氏筛法

筛法求素数的几个模板

埃式筛法筛选素数 PAT1013

HDOJ 6069 素数筛法(数学)

素数的筛法