初学Java,学到流程控制的循环,有个练习题是暴力遍历素数。
因为看过av32186751,知道有个筛法,就想试试。
引用文字:
我们先定义一个数组来存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