NowCoder猜測

1 題目描述

  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是否是正確的,也許還能夠得諾貝爾獎呢。^_^數組

1.1 輸入描述:

  輸入包括多組數據。
  每組數據僅有一個整數n (1≤n≤10000000)。函數

1.2 輸出描述:

  對於每組數據輸入,輸出一行,爲1->n(包括n)之間的素數的個數。測試

1.3 輸入例子:

1
10
65
100
0

 

1.4 輸出例子:

0
4
18
25

 

2 解題思路

  採用標記法求素數個數,假如輸入是100,求100的平方根,獲得10,再開闢大小爲101的數組空間,將先將2倍數,但不包括2標記爲非素數。現找下一個未標記的素數3,將3倍數,但不包括3標記爲非素數。以此類推直到找到的素數大於10爲止。最後統計未標記的數,那些數就是所求的素數。圖2-1是之內的質數求解方法。
這裏寫圖片描述
  圖2-1 100 之內的質數求解spa

3 算法實現

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;
    }
}

4 測試結果

這裏寫圖片描述

相關文章
相關標籤/搜索