How can I test for primality?

前端 未结 16 2190
南方客
南方客 2020-12-05 08:29

I am writing a little library with some prime number related methods. As I\'ve done the groundwork (aka working methods) and now I\'m looking for some optimization. Ofcours

16条回答
  •  暖寄归人
    2020-12-05 08:39

    Sadly, I haven't tried the algorithmic approaches before. But if you want to implement your approach efficiently, I'd suggest doing some caching. Create an array to store all prime numbers less than a defined threshold, fill this array, and search within/using it.

    In the following example, finding whether a number is prime is O(1) in the best case (namely, when the number is less than or equal to maxPrime, which is 821,461 for a 64K buffer), and is somewhat optimized for other cases (by checking mod over only 64K numbers out of the first 820,000 -- about 8%).

    (Note: Don't take this answer as the "optimal" approach. It's more of an example on how to optimize your implementation.)

    public static class PrimeChecker
    {
        private const int BufferSize = 64 * 1024; // 64K * sizeof(int) == 256 KB
    
        private static int[] primes;
        public static int MaxPrime { get; private set; }
    
        public static bool IsPrime(int value)
        {
            if (value <= MaxPrime)
            {
                return Array.BinarySearch(primes, value) >= 0;
            }
            else
            {
                return IsPrime(value, primes.Length) && IsLargerPrime(value);
            }
        }
    
        static PrimeChecker()
        {
            primes = new int[BufferSize];
            primes[0] = 2;
            for (int i = 1, x = 3; i < primes.Length; x += 2)
            {
                if (IsPrime(x, i))
                    primes[i++] = x;
            }
            MaxPrime = primes[primes.Length - 1];
        }
    
        private static bool IsPrime(int value, int primesLength)
        {
            for (int i = 0; i < primesLength; ++i)
            {
                if (value % primes[i] == 0)
                    return false;
            }
            return true;
        }
    
        private static bool IsLargerPrime(int value)
        {
            int max = (int)Math.Sqrt(value);
            for (int i = MaxPrime + 2; i <= max; i += 2)
            {
                if (value % i == 0)
                    return false;
            }
            return true;
        }
    }
    

提交回复
热议问题