Eratosthenes筛选法

来源:互联网 发布:java实现迭代器 编辑:程序博客网 时间:2024/06/05 07:40

说到素数,最基本的算是一百以内的那些数了。这些数在数学竟赛中常常会被用到。比如说有这样一道题:“一百以内有多少在加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;            }        }    }}

 

原创粉丝点击