nowcoder在家極度無聊,因而找了張紙開始統計素數的個數。設函數f(n)返回從1-n之間素數的個數。nowcoder 發現:java
f(1) = 0
f(10) = 4
f(100) = 25
…
知足g(m) = 17 * m^2 / 3 - 22 * m / 3 + 5 / 3
其中m爲n的位數。算法
他很激動,是否是本身發現了素數分佈的規律了!
請你設計一個程序,求出f(n),來驗證nowcoder是否是正確的,也許還能夠得諾貝爾獎呢。^_^數組
輸入包括多組數據。
每組數據僅有一個整數n (1≤n≤10000000)。函數
對於每組數據輸入,輸出一行,爲1->n(包括n)之間的素數的個數。測試
1 10 65 100 0
0 4 18 25
採用標記法求素數個數,假如輸入是100,求100的平方根,獲得10,再開闢大小爲101的數組空間,將先將2倍數,但不包括2標記爲非素數。現找下一個未標記的素數3,將3倍數,但不包括3標記爲非素數。以此類推直到找到的素數大於10爲止。最後統計未標記的數,那些數就是所求的素數。圖2-1是之內的質數求解方法。
圖2-1 100 之內的質數求解spa
import java.util.Scanner; /** * All Rights Reserved !!! */ public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); // Scanner scanner = new Scanner(Main.class.getClassLoader().getResourceAsStream("data.txt")); while (scanner.hasNext()) { int n = scanner.nextInt(); if (n >= 1 && n <= 10_000_000) { System.out.println(guess(n)); } } scanner.close(); } /** * 求[1, n]中素數的個數,使用標記法 * * @param n 最大的範圍 * @return 素數個數 */ private static int guess(int n) { // 標記是不是素數 // false表示是素數 // true表示不是素數 boolean[] mark = new boolean[n + 1]; mark[0] = true; mark[1] = true; // 標記質數 for (int i = 2; i < mark.length; i++) { // i是質數 if (!mark[i]) { for (int j = 2 * i; j < mark.length; j += i) { mark[j] = true; } } } // 統計質數個數 int count = 0; for (int i = 2; i < mark.length; i++) { if (!mark[i]) { count++; } } return count; } }