說到素數,最基本的算是一百以內的那些數了。這些數在數學竟賽中常常會被用到。比如說有這樣一道題:“一百以內有多少在加2後仍然是素數的素數?”11和17就是這樣的素數。如果對素數很熟悉的話,就能迅速得出答案。
那麼,給定一個一百以內的數,如何迅速判斷它是不是素數呢?
一個最簡單的方發就是“埃拉託斯特尼篩法” (Sieve of Eratosthenes)。如上圖所示,給出要篩數值的範圍n,找出n√以內的素數p1,p2,…,pk。先用2去篩,即把2留下,把2的倍數剔除掉;再用下一個素數,也就是3篩,把3留下,把3的倍數剔除掉;接下去用下一個素數5篩,把5留下,把5的倍數剔除掉;不斷重複下去......。
using System; using System.Collections.Generic; using System.Text; namespace 產生素數 { class PrimeGenerator { private static bool[] crossedOut; private static int[] result; public static int[] GeneratePrimeNumbers(int maxValue) { if (maxValue < 2) { return new int[0]; } else { UncrossIntegersUpTo(maxValue); CrossOutMultiples(); PutUncrossedIntegersIntoResult(); return result; } } private static void PutUncrossedIntegersIntoResult() { result = new int[NumberOfUncrossedIntegers()]; for (int j = 0, i = 2; i < crossedOut.Length; i++) { if (NotCrossed(i)) { result[j++] = i; } } } private static bool NotCrossed(int i) { return crossedOut[i] == false; } private static int NumberOfUncrossedIntegers() { int count = 0; for(int i=2;i<crossedOut.Length;i++) { if (NotCrossed(i)) { count++; } } return count; } private static void CrossOutMultiples() { int limit = DetermineIterationLimit(); for (int i = 2; i <= limit; i++) { if (NotCrossed(i)) { CrossOutMultiplesOf(i); } } } private static void CrossOutMultiplesOf(int i) { for(int multiple=2*i;multiple<crossedOut.Length;multiple+=i) { Console.WriteLine("multiple{0} {1}", multiple,i); crossedOut[multiple] = true; } } private static int DetermineIterationLimit() { double interationLimit = Math.Sqrt(crossedOut.Length); return (int)interationLimit; } private static void UncrossIntegersUpTo(int maxValue) { crossedOut = new bool[maxValue + 1]; for (int i = 2; i < crossedOut.Length; i++) { crossedOut[i] = false; } } } }