प्राइम नंबर जनरेट करने का सबसे सुरुचिपूर्ण तरीका [बंद]


84

इस समारोह को लागू करने का सबसे सुंदर तरीका क्या है:

ArrayList generatePrimes(int n)

यह फ़ंक्शन पहले nप्राइम्स बनाता है (संपादित करें: जहां n>1), इसलिए generatePrimes(5)एक ArrayListसाथ वापस आ जाएगा {2, 3, 5, 7, 11}। (मैं इसे C # में कर रहा हूं, लेकिन मैं जावा कार्यान्वयन से खुश हूं - या उस मामले के लिए कोई अन्य समान भाषा (इसलिए हास्केल नहीं))।

मुझे नहीं पता कि यह फ़ंक्शन कैसे लिखना है, लेकिन जब मैंने कल रात किया तो यह उतना अच्छा नहीं हुआ जितना मैं उम्मीद कर रहा था। यहां वह है जो मैंने जुटाया:

ArrayList generatePrimes(int toGenerate)
{
    ArrayList primes = new ArrayList();
    primes.Add(2);
    primes.Add(3);
    while (primes.Count < toGenerate)
    {
        int nextPrime = (int)(primes[primes.Count - 1]) + 2;
        while (true)
        {
            bool isPrime = true;
            foreach (int n in primes)
            {
                if (nextPrime % n == 0)
                {
                    isPrime = false;
                    break;
                }
            }
            if (isPrime)
            {
                break;
            }
            else
            {
                nextPrime += 2;
            }
        }
        primes.Add(nextPrime);
    }
    return primes;
}

मैं गति के बारे में बहुत चिंतित नहीं हूं, हालांकि मैं नहीं चाहता कि यह स्पष्ट रूप से अक्षम हो। मुझे कोई आपत्ति नहीं है कि किस विधि का उपयोग किया जाता है (भोली या छलनी या कुछ और), लेकिन मैं चाहता हूं कि यह काफी छोटा और स्पष्ट हो कि यह कैसे काम करता है।

संपादित करें : उन सभी के लिए धन्यवाद जिन्होंने जवाब दिया है, हालांकि कई ने मेरे वास्तविक सवाल का जवाब नहीं दिया। दोहराना करने के लिए, मुझे कोड का एक अच्छा साफ टुकड़ा चाहिए था जो अभाज्य संख्याओं की सूची तैयार करता है। मैं पहले से ही जानता हूं कि इसे अलग-अलग तरीकों से कैसे करना है, लेकिन मैं कोड लिखने के लिए प्रवृत्त हूं जो उतना स्पष्ट नहीं है जितना यह हो सकता है। इस धागे में कुछ अच्छे विकल्प प्रस्तावित किए गए हैं:

  • मूल रूप से मेरे पास जो कुछ भी था, उसका एक पीटर संस्करण (पीटर स्मिट, jmservera और Rekreativc)
  • एराटोस्थनीज (स्टारब्ले) की छलनी का बहुत साफ कार्यान्वयन
  • जावा का उपयोग करें BigIntegerऔरnextProbablePrime बहुत ही सरल कोड के लिए, हालांकि मैं कल्पना नहीं कर सकता कि यह विशेष रूप से कुशल है (dfa)
  • प्रिज़्म (Maghis) की सूची बनाने के लिए LINQ का उपयोग करें
  • एक पाठ फ़ाइल में बहुत सारे अपराध रखें और जब आवश्यक हो तो उन्हें पढ़ें (darin)

संपादित करें 2 : मैंने C # यहां दिए गए तरीकों के एक जोड़े में लागू किया है , और एक अन्य विधि जिसका उल्लेख यहां नहीं किया गया है। वे सभी पहले एन प्राइम को प्रभावी ढंग से पाते हैं (और मेरे पास सिस्टर्स को प्रदान करने की सीमा खोजने का एक अच्छा तरीका है)।


12
नहीं, और यह प्रोजेक्ट यूलर के लिए नहीं है या तो :-)
डेविड जॉनस्टोन

1
यह बेहतर होगा कि मुझे ienumerable <int> को पीछे हटाना और एक
फेलिस पोलानो

4
मैं जानना चाहता हूं कि अभाज्य संख्याएँ उत्पन्न करने का सबसे कम सुंदर तरीका क्या है । मैं एक एक्सेस डेटाबेस को शामिल करते हुए कुछ सोच रहा हूँ?
j_random_hacker

1
तुलना के लिए, एक BMeph 2008 हास्केल कोड : nubBy (((>1).).gcd) [2..]। यह 2 से शुरू होने वाले प्राकृतिक नंबरों के बीच केवल गैर-डुप्लिकेट छोड़ता है, जबकि किसी भी संख्या को डुप्लिकेट के रूप में विचार करते हैं, gcdजिसमें पहले से मिली संख्याओं में से कोई भी 1 से अधिक है। यह उत्पादित अपराधों की संख्या में बहुत अक्षम, द्विघात है। लेकिन यह सुरुचिपूर्ण है
Ness

सबसे सुंदर , IMO, हास्केल है, import Data.List.Ordered ; let { _Y g = g (_Y g) ; primes = 2 : _Y( (3:) . minus [5,7..] . unionAll . map (\p-> [p*p, p*p+p*2..]) ) }लेकिन यह पूरी तरह से राय आधारित है
विल नेस 10

जवाबों:


48

अनुमान का उपयोग करें

pi(n) = n / log(n)

एक सीमा को खोजने के लिए n तक की प्राइम्स की संख्या के लिए, और फिर एक छलनी का उपयोग करें। अनुमान कुछ हद तक एन की संख्या को कम करके आंकता है, इसलिए चलनी आवश्यकता से थोड़ी बड़ी होगी, जो ठीक है।

यह मेरा मानक जावा चलनी है, एक सामान्य लैपटॉप पर एक सेकंड में पहले मिलियन प्राइम की गणना करता है:

public static BitSet computePrimes(int limit)
{
    final BitSet primes = new BitSet();
    primes.set(0, false);
    primes.set(1, false);
    primes.set(2, limit, true);
    for (int i = 0; i * i < limit; i++)
    {
        if (primes.get(i))
        {
            for (int j = i * i; j < limit; j += i)
            {
                primes.clear(j);
            }
        }
    }
    return primes;
}

3
इरेटोस्थनीज़ की छलनी का बहुत अच्छा कार्यान्वयन है
डेविड जॉनस्टोन

1
i <= Math.sqrt(limit)बाहरी लूप में रहते हुए यह लूप करने के लिए पर्याप्त नहीं है ?
क्रिस्टोफ

1
@ डेविड जॉनस्टोन नहीं, पीआई (एन) = एन / लॉग (एन) एन तक की संख्या को कम करता है, जो विपरीत दिशा में जाता है। मुझे खुशी है कि आपको एक बहुत अच्छा लग रहा था, हालांकि।
स्टारब्ल्यू

1
यदि आप अपने स्वयं के लूप में 2 के सभी गुणकों को हटाने के लिए तैयार हैं, तो आप कुछ अतिरिक्त रनटाइम को बचाने के लिए अपने लूप वेतन वृद्धि के रूप में j + = 2 * i का उपयोग कर सकते हैं, और आप गणना कर सकते हैं कि एक बार थोड़ी शिफ्ट का उपयोग करके
निक लार्सन

5
को बदलकर BitSet2, 3 और 5 के लिए एक वर्ग को लागू करने पहिया गुणन से यह लगभग 3 गुना तेजी से हो जाता है।
Starblue

37

सभी को बहुत धन्यवाद जिन्होंने मददगार जवाब दिए। यहाँ C # में पहले n primes खोजने के कुछ अलग तरीकों का मेरा कार्यान्वयन है । पहले दो तरीके बहुत ज्यादा हैं जो यहां पोस्ट किए गए थे। (पोस्टर्स के नाम शीर्षक के बगल में हैं।) मैं कुछ समय में एटकिन की छलनी करने की योजना बना रहा हूं, हालांकि मुझे संदेह है कि यह वर्तमान में यहां के तरीकों की तरह सरल नहीं होगा। अगर कोई भी इनमें से किसी भी तरीके को सुधारने का कोई तरीका देख सकता है तो मुझे यह जानकर बहुत अच्छा लगेगा :-)

मानक विधि ( पीटर स्मिट , jmservera , Rekreativc )

पहली अभाज्य संख्या है 2. इसे प्रिम्स की सूची में जोड़ें। अगला प्राइम अगला नंबर है जो इस सूची में किसी भी संख्या से समान रूप से विभाज्य नहीं है।

public static List<int> GeneratePrimesNaive(int n)
{
    List<int> primes = new List<int>();
    primes.Add(2);
    int nextPrime = 3;
    while (primes.Count < n)
    {
        int sqrt = (int)Math.Sqrt(nextPrime);
        bool isPrime = true;
        for (int i = 0; (int)primes[i] <= sqrt; i++)
        {
            if (nextPrime % primes[i] == 0)
            {
                isPrime = false;
                break;
            }
        }
        if (isPrime)
        {
            primes.Add(nextPrime);
        }
        nextPrime += 2;
    }
    return primes;
}

यह परीक्षण किया जा रहा संख्या के वर्गमूल तक विभाज्यता के लिए केवल परीक्षण द्वारा अनुकूलित किया गया है; और केवल विषम संख्याओं का परीक्षण करके। यह प्रपत्र के केवल नंबरों 6k+[1, 5], 30k+[1, 7, 11, 13, 17, 19, 23, 29]या इसी तरह परीक्षण करके आगे अनुकूलित किया जा सकता है ।

एराटोस्थनीज ( स्टारब्ले ) की चलनी

यह k को सभी primes ढूँढता है । पहले n primes की सूची बनाने के लिए , हमें सबसे पहले n th prime के अनुमानित मूल्य की आवश्यकता है । निम्नलिखित विधि, जैसा कि यहां वर्णित है , यह करता है।

public static int ApproximateNthPrime(int nn)
{
    double n = (double)nn;
    double p;
    if (nn >= 7022)
    {
        p = n * Math.Log(n) + n * (Math.Log(Math.Log(n)) - 0.9385);
    }
    else if (nn >= 6)
    {
        p = n * Math.Log(n) + n * Math.Log(Math.Log(n));
    }
    else if (nn > 0)
    {
        p = new int[] { 2, 3, 5, 7, 11 }[nn - 1];
    }
    else
    {
        p = 0;
    }
    return (int)p;
}

// Find all primes up to and including the limit
public static BitArray SieveOfEratosthenes(int limit)
{
    BitArray bits = new BitArray(limit + 1, true);
    bits[0] = false;
    bits[1] = false;
    for (int i = 0; i * i <= limit; i++)
    {
        if (bits[i])
        {
            for (int j = i * i; j <= limit; j += i)
            {
                bits[j] = false;
            }
        }
    }
    return bits;
}

public static List<int> GeneratePrimesSieveOfEratosthenes(int n)
{
    int limit = ApproximateNthPrime(n);
    BitArray bits = SieveOfEratosthenes(limit);
    List<int> primes = new List<int>();
    for (int i = 0, found = 0; i < limit && found < n; i++)
    {
        if (bits[i])
        {
            primes.Add(i);
            found++;
        }
    }
    return primes;
}

सुंदरम की छलनी

मैंने हाल ही में इस छलनी की खोज की , लेकिन इसे काफी सरलता से लागू किया जा सकता है। मेरा कार्यान्वयन एराटोस्थनीज़ की छलनी जितना तेज़ नहीं है, लेकिन यह भोली विधि से काफी तेज है।

public static BitArray SieveOfSundaram(int limit)
{
    limit /= 2;
    BitArray bits = new BitArray(limit + 1, true);
    for (int i = 1; 3 * i + 1 < limit; i++)
    {
        for (int j = 1; i + j + 2 * i * j <= limit; j++)
        {
            bits[i + j + 2 * i * j] = false;
        }
    }
    return bits;
}

public static List<int> GeneratePrimesSieveOfSundaram(int n)
{
    int limit = ApproximateNthPrime(n);
    BitArray bits = SieveOfSundaram(limit);
    List<int> primes = new List<int>();
    primes.Add(2);
    for (int i = 1, found = 1; 2 * i + 1 <= limit && found < n; i++)
    {
        if (bits[i])
        {
            primes.Add(2 * i + 1);
            found++;
        }
    }
    return primes;
}

FYI करें - मुझे एक अतिप्रवाह को रोकने के लिए आपके मुख्य लूप काउंटर को "for (int i = 0; i * i <= limit && i * i> 0; i ++)" में बदलना था।
याकूब डेटा सॉल्यूशंस

सुंदरम की छलनी का यह क्रियान्वयन वहां के बहुत कम सही लोगों में से एक है। उनमें से अधिकांश i+j+2*i*jगलत आउटपुट के लिए अग्रणी की गणना करते समय, i और j के लिए गलत सीमा का उपयोग करते हैं ।
जहकबेथ

14

एक पुराने प्रश्न का निस्तारण, लेकिन मैं LINQ के साथ खेलते समय इस पर लड़खड़ा गया।

इस कोड को समानांतर एक्सटेंशन के साथ .NET4.0 या .NET3.5 की आवश्यकता है

public List<int> GeneratePrimes(int n) {
    var r = from i in Enumerable.Range(2, n - 1).AsParallel()
            where Enumerable.Range(1, (int)Math.Sqrt(i)).All(j => j == 1 || i % j != 0)
            select i;
    return r.ToList();
}

1
यह स्वीकृत उत्तर क्यों नहीं है? स्वीकृत उत्तर में कोड की तुलना में यहां कोड बहुत छोटा, अधिक सुरुचिपूर्ण और तेज़ है। काश मैं एक से अधिक बार उत्थान कर पाता!
एवरहोम यिसरेल

9

आप अच्छे रास्ते पर हैं।

कुछ टिप्पणियां

  • primes.Add (3); बनाता है कि यह फ़ंक्शन संख्या = 1 के लिए काम नहीं करता है

  • आपको प्राइमरनस के साथ विभाजन का परीक्षण करने की आवश्यकता नहीं है जो कि परीक्षण किए जाने वाले संख्या के वर्गरूट को बड़ा करता है।

सुझाया गया कोड:

ArrayList generatePrimes(int toGenerate)
{
    ArrayList primes = new ArrayList();

    if(toGenerate > 0) primes.Add(2);

    int curTest = 3;
    while (primes.Count < toGenerate)
    {

        int sqrt = (int) Math.sqrt(curTest);

        bool isPrime = true;
        for (int i = 0; i < primes.Count && primes.get(i) <= sqrt; ++i)
        {
            if (curTest % primes.get(i) == 0)
            {
                isPrime = false;
                break;
            }
        }

        if(isPrime) primes.Add(curTest);

        curTest +=2
    }
    return primes;
}

1
उस प्राइम * प्राइम का परीक्षण करना = वर्गमूल की पूर्व-गणना के बजाय लूप में curTest शायद इसे और तेज़ कर देगा और इसे और अधिक सामान्य बना देगा (bignums, आदि के लिए काम करेगा)
yairchu

वर्गमूल का उपयोग क्यों? ऐसे विकल्प के लिए गणितीय पृष्ठभूमि क्या है? मैं, शायद नीरस, केवल 2. से विभाजित होगा
लुइस फ़िलिप

3
क्योंकि अगर किसी संख्या के प्रमुख कारक हैं, तो उनमें से कम से कम एक वर्गमूल से कम या बराबर होना चाहिए। यदि एक * बी = सी और एक <= बी तो एक <= sqrt (सी) <= बी।
डेविड जॉनस्टोन

8

आप संभावित अपराधों पर एक नज़र रखना चाहिए । विशेष रूप से रैंडमाइज्ड अल्गोरिद्म और मिलर-राबिन प्राइमलिटी टेस्ट पर एक नज़र डालें ।

पूर्णता के लिए आप सिर्फ java.math का उपयोग कर सकते हैं। BigInteger :

public class PrimeGenerator implements Iterator<BigInteger>, Iterable<BigInteger> {

    private BigInteger p = BigInteger.ONE;

    @Override
    public boolean hasNext() {
        return true;
    }

    @Override
    public BigInteger next() {
        p = p.nextProbablePrime();
        return p;
    }

    @Override
    public void remove() {
        throw new UnsupportedOperationException("Not supported.");
    }

    @Override
    public Iterator<BigInteger> iterator() {
        return this;
    }
}

@Test
public void printPrimes() {
    for (BigInteger p : new PrimeGenerator()) {
        System.out.println(p);
    }
}

2
मिलर-राबिन बहुत तेज है और कोड बहुत सरल है। इसे पर्याप्त पुनरावृत्तियों देते हुए यह एक झूठे सकारात्मक की संभावना के मामले में यादृच्छिक सीपीयू विफलता के साथ प्रतिस्पर्धा में पर्याप्त विश्वसनीय बनाता है। एल्गोरिथ्म का नकारात्मक पक्ष यह है कि यह समझना कि यह वास्तव में क्यों काम करता है एक मुश्किल काम है।
ब्रायन

6

कोई मतलब नहीं है, लेकिन शायद सबसे पठनीय:

public static IEnumerable<int> GeneratePrimes()
{
   return Range(2).Where(candidate => Range(2, (int)Math.Sqrt(candidate)))
                                     .All(divisor => candidate % divisor != 0));
}

साथ में:

public static IEnumerable<int> Range(int from, int to = int.MaxValue)
{
   for (int i = from; i <= to; i++) yield return i;
}

वास्तव में यहाँ कुछ पदों की भिन्नता के साथ यहाँ अच्छे स्वरूपण हैं।


5

CC-BY-SA लाइसेंस https://creativecommons.org/licenses/by-sa/3.0/ के तहत St.Wittum 13189 बर्लिन जर्मनी द्वारा कॉपीराइट 2009

सभी PRIMES की गणना करने का सरल लेकिन सबसे सुंदर तरीका यह होगा, लेकिन यह तरीका धीमा है और उच्चतर संख्याओं के लिए मेमोरी लागत बहुत अधिक है क्योंकि संकाय (!) फ़ंक्शन का उपयोग करते हुए ... लेकिन यह एक आवेदन में विल्सन प्रमेय की भिन्नता को प्रदर्शित करता है। अजगर द्वारा कार्यान्वित एल्गोरिथ्म द्वारा सभी अपराध उत्पन्न करते हैं

#!/usr/bin/python
f=1 # 0!
p=2 # 1st prime
while True:
    if f%p%2:
        print p
    p+=1
    f*=(p-2)

4

Primes.txt बनाने के लिए एक प्राइम नंबर जनरेटर का उपयोग करें और फिर:

class Program
{
    static void Main(string[] args)
    {
        using (StreamReader reader = new StreamReader("primes.txt"))
        {
            foreach (var prime in GetPrimes(10, reader))
            {
                Console.WriteLine(prime);
            }
        }
    }

    public static IEnumerable<short> GetPrimes(short upTo, StreamReader reader)
    {
        int count = 0;
        string line = string.Empty;
        while ((line = reader.ReadLine()) != null && count++ < upTo)
        {
            yield return short.Parse(line);
        }
    }
}

इस स्थिति में मैं विधि हस्ताक्षर में Int16 का उपयोग करता हूं, इसलिए मेरी primes.txt फ़ाइल में 0 से 32767 तक संख्याएँ हैं। यदि आप इसे Int32 में विस्तारित करना चाहते हैं या Int64 में आपका primes.txt काफी बड़ा हो सकता है।


3
ओपी का हवाला देते हुए: "मुझे कोई आपत्ति नहीं है कि किस विधि का उपयोग किया जाता है (भोली या छलनी या कुछ और), लेकिन मैं चाहता हूं कि यह काफी छोटा और स्पष्ट हो कि यह कैसे काम करता है"। मुझे लगता है कि मेरा जवाब पूरी तरह से प्रासंगिक है। यह सबसे तेज विधि भी है।
डारिन दिमित्रोव

14
यहां तक ​​कि अगर वह कहता है, "मुझे कोई आपत्ति नहीं है कि कौन सी विधि ..." मुझे नहीं लगता कि इसमें "अपराधों की सूची खोलना" शामिल है। यह "कंप्यूटर खरीदने के लिए" कंप्यूटर का निर्माण करने के प्रश्न का उत्तर देने जैसा होगा। -1
स्टीवन्वह

8
यह तेजी से होगा यदि आप वास्तव में प्राइम कोड को स्रोत कोड में ही लिखते हैं, बजाय उन्हें किसी फ़ाइल से पढ़ने के।
डैनियल डारनास

3
बहुत स्मृति का उपभोग करें? पाठ के रूप में पूर्ण primes सूची पढ़ने से अधिक ... स्मृति? क्या आप जानते हैं कि तार किस तरह से काम करते हैं।
jmservera

6
Primes की सूची एक अनंत लेकिन अपरिवर्तनीय सूची है, इसलिए यह आवेदन के लिए संभावित ऊपरी सीमा तक एक पूर्वकाल की सूची का उपयोग करने के लिए प्रीफेक्ट समझ में आता है। क्यों समय बर्बाद करने वाला कोड लिखना जो एक छोटी सार्वजनिक सूची उपलब्ध हो सकती है, जिसका उपयोग आवश्यकताओं को पूरा करने के लिए किया जा सकता है।
एंडीएम

4

मैं निम्नलिखित सी # समाधान की पेशकश कर सकता हूं। यह किसी भी तरह से तेज नहीं है, लेकिन यह इसके बारे में बहुत स्पष्ट है कि यह क्या करता है।

public static List<Int32> GetPrimes(Int32 limit)
{
    List<Int32> primes = new List<Int32>() { 2 };

    for (int n = 3; n <= limit; n += 2)
    {
        Int32 sqrt = (Int32)Math.Sqrt(n);

        if (primes.TakeWhile(p => p <= sqrt).All(p => n % p != 0))
        {
            primes.Add(n);
        }
    }

    return primes;
}

मैंने कोई भी जाँच छोड़ दी - यदि सीमा नकारात्मक है या दो से छोटी है (फिलहाल यह विधि कम से कम दो को अभाज्य के रूप में लौटा देगी)। लेकिन यह सब ठीक करना आसान है।

अपडेट करें

निम्नलिखित दो विस्तार विधियों को समझें

public static void Do<T>(this IEnumerable<T> collection, Action<T> action)
{
    foreach (T item in collection)
    {
        action(item);
    }
}

public static IEnumerable<Int32> Range(Int32 start, Int32 end, Int32 step)
{
    for (int i = start; i < end; i += step)
    }
        yield return i;
    }
}

आप इसे निम्नानुसार फिर से लिख सकते हैं।

public static List<Int32> GetPrimes(Int32 limit)
{
    List<Int32> primes = new List<Int32>() { 2 };

    Range(3, limit, 2)
        .Where(n => primes
            .TakeWhile(p => p <= Math.Sqrt(n))
            .All(p => n % p != 0))
        .Do(n => primes.Add(n));

    return primes;
}

यह कम कुशल है (क्योंकि वर्गमूल के रूप में काफी बार पुनर्मूल्यांकित किया गया है) लेकिन यह क्लीनर कोड भी है। यह संभव है कि प्रिज्मों की गणना करने के लिए कोड को फिर से लिखा जाए, लेकिन यह कोड को काफी अव्यवस्थित कर देगा।


मैं लगभग सकारात्मक हूं कि वर्गमूल की गणना जेआईटी संकलक द्वारा अनुकूलित की जाती है (जब अनुकूलन सक्षम के साथ संकलित किया जाता है)। उत्पन्न विधानसभा की जांच करके आपको यह सत्यापित करना होगा (IL केवल आंशिक रूप से अनुकूलित है और JIT कंपाइलर द्वारा निष्पादित अनुकूलन के पास कहीं नहीं है। लूप फहराने और अन्य सूक्ष्म अनुकूलन के दिन समाप्त हो गए हैं। वास्तव में, कभी-कभी कोशिश कर रहा है। आउट JIT आपके कोड को धीमा कर सकती है ।
डेव ब्लैक

4

यहाँ सी # में एराटोस्थनीज की छलनी का कार्यान्वयन है :

    IEnumerable<int> GeneratePrimes(int n)
    {
        var values = new Numbers[n];

        values[0] = Numbers.Prime;
        values[1] = Numbers.Prime;

        for (int outer = 2; outer != -1; outer = FirstUnset(values, outer))
        {
            values[outer] = Numbers.Prime;

            for (int inner = outer * 2; inner < values.Length; inner += outer)
                values[inner] = Numbers.Composite;
        }

        for (int i = 2; i < values.Length; i++)
        {
            if (values[i] == Numbers.Prime)
                yield return i;
        }
    }

    int FirstUnset(Numbers[] values, int last)
    {
        for (int i = last; i < values.Length; i++)
            if (values[i] == Numbers.Unset)
                return i;

        return -1;
    }

    enum Numbers
    {
        Unset,
        Prime,
        Composite
    }

मैं enum के बजाय एक बूल के साथ ऐसा करूँगा ...
Letterman

3

अपने इसी एल्गोरिथ्म का उपयोग करके आप इसे थोड़ा छोटा कर सकते हैं:

List<int> primes=new List<int>(new int[]{2,3});
for (int n = 5; primes.Count< numberToGenerate; n+=2)
{
  bool isPrime = true;
  foreach (int prime in primes)
  {
    if (n % prime == 0)
    {
      isPrime = false;
      break;
    }
  }
  if (isPrime)
    primes.Add(n);
}

3

मुझे पता है कि आपने गैर-हास्केल समाधान के लिए कहा था, लेकिन मैं यहां इसे शामिल कर रहा हूं क्योंकि यह प्रश्न से संबंधित है और इस तरह की चीज के लिए हास्केल भी सुंदर है।

module Prime where

primes :: [Integer]
primes = 2:3:primes'
  where
    -- Every prime number other than 2 and 3 must be of the form 6k + 1 or 
    -- 6k + 5. Note we exclude 1 from the candidates and mark the next one as
    -- prime (6*0+5 == 5) to start the recursion.
    1:p:candidates = [6*k+r | k <- [0..], r <- [1,5]]
    primes'        = p : filter isPrime candidates
    isPrime n      = all (not . divides n) $ takeWhile (\p -> p*p <= n) primes'
    divides n p    = n `mod` p == 0

हाँ, मैं हास्केल का भी बहुत बड़ा प्रशंसक हूँ (मेरी इच्छा है कि मैं इसे बेहतर जानता था)
डेविड जॉनस्टोन

3

मैंने कुछ LINQ का उपयोग करके c # में एक सरल Eratosthenes कार्यान्वयन लिखा।

दुर्भाग्य से LINQ चींटियों का अनंत क्रम प्रदान नहीं करता है इसलिए आपको int.MaxValue का उपयोग करना होगा :(

मुझे प्रत्येक कैश्ड प्राइम (थोड़ा सा बदसूरत) के लिए गणना करने से बचने के लिए उम्मीदवार वर्गर्ट को अनॉनिमस प्रकार में कैश करना पड़ा।

मैं उम्मीदवार की sqrt तक पिछले अपराधों की एक सूची का उपयोग करता हूं

cache.TakeWhile(c => c <= candidate.Sqrt)

और इसके खिलाफ 2 से शुरू होने वाले हर इंट की जांच करें

.Any(cachedPrime => candidate.Current % cachedPrime == 0)

यहाँ कोड है:

static IEnumerable<int> Primes(int count)
{
    return Primes().Take(count);
}

static IEnumerable<int> Primes()
{
    List<int> cache = new List<int>();

    var primes = Enumerable.Range(2, int.MaxValue - 2).Select(candidate => new 
    {
        Sqrt = (int)Math.Sqrt(candidate), // caching sqrt for performance
        Current = candidate
    }).Where(candidate => !cache.TakeWhile(c => c <= candidate.Sqrt)
            .Any(cachedPrime => candidate.Current % cachedPrime == 0))
            .Select(p => p.Current);

    foreach (var prime in primes)
    {
        cache.Add(prime);
        yield return prime;
    }
}

एक और अनुकूलन सूची से बचने के लिए भी है और सूची बनाने से पहले सिर्फ 2 को वापस करें। इस तरह से अगर कॉलिंग विधि सिर्फ 1 अभियो के लिए कहती है तो यह सभी गड़बड़ियों से बच जाएगी:

static IEnumerable<int> Primes()
{
    yield return 2;
    List<int> cache = new List<int>() { 2 };

    var primes = Enumerable.Range(3, int.MaxValue - 3)
        .Where(candidate => candidate % 2 != 0)
        .Select(candidate => new
    {
        Sqrt = (int)Math.Sqrt(candidate), // caching sqrt for performance
        Current = candidate
    }).Where(candidate => !cache.TakeWhile(c => c <= candidate.Sqrt)
            .Any(cachedPrime => candidate.Current % cachedPrime == 0))
            .Select(p => p.Current);

    foreach (var prime in primes)
    {
        cache.Add(prime);
        yield return prime;
    }
}

1
काश, मैं LINQ को इस उत्तर को बेहतर ढंग से सराहना और समझने के लिए जानता था :-) इसके अलावा, मुझे लगता है कि यह एराटोस्थनीज की छलनी का कार्यान्वयन नहीं है, और यह वैचारिक रूप से मेरे मूल कार्य के समान काम करता है (अगला ढूंढें) वह संख्या जो पहले पाए गए प्राइम में से किसी के द्वारा विभाज्य नहीं है)।
डेविड जॉनस्टोन

हां, लेकिन "अगले नंबर को ढूंढें जो पहले पाए गए प्राइम्स (छोटे तब संख्या) में से किसी के द्वारा विभाज्य नहीं है" वैचारिक रूप से एराटोस्थनीज की छलनी के समान है। यदि आप पसंद करते हैं, तो मैं इसे थोड़ा और अधिक पढ़ने योग्य बना सकता हूं, भले ही आप LINQ से परिचित न हों। क्या आप पुनरावृत्तियों से परिचित हैं?
मगही

मुझे इस दृष्टिकोण की बात पसंद है कि अगला प्राइम की गणना बस तब की जाती है जब कॉलर इसके लिए कहता है, इसलिए "पहले n primes ले" या "primes ले लो जो छोटे हैं तो n" तुच्छ हो जाते हैं
Maghis

1
धन्यवाद, लेकिन मैं समझ सकता हूं कि कम या ज्यादा यह पता है कि यह क्या कर रहा है :-) मुझे आलसी मूल्यांकन पसंद है, लेकिन मैं अभी भी इसे एराटोस्थनीज की छलनी का कार्यान्वयन नहीं कहूंगा।
डेविड जॉनस्टोन

1

इसे और अधिक सुरुचिपूर्ण बनाने के लिए, आपको अपने IsPrime परीक्षण को एक अलग विधि में फिर से तैयार करना चाहिए, और उस के बाहर लूपिंग और वेतन वृद्धि को संभालना चाहिए।


1

मैंने इसे जावा में एक कार्यात्मक पुस्तकालय का उपयोग किया था जिसे मैंने लिखा था, लेकिन चूँकि मेरी लाइब्रेरी समान अवधारणाओं का उपयोग करती है, मुझे यकीन है कि कोड अनुकूलनीय है:

Iterable<Integer> numbers = new Range(1, 100);
Iterable<Integer> primes = numbers.inject(numbers, new Functions.Injecter<Iterable<Integer>, Integer>()
{
    public Iterable<Integer> call(Iterable<Integer> numbers, final Integer number) throws Exception
    {
        // We don't test for 1 which is implicit
        if ( number <= 1 )
        {
            return numbers;
        }
        // Only keep in numbers those that do not divide by number
        return numbers.reject(new Functions.Predicate1<Integer>()
        {
            public Boolean call(Integer n) throws Exception
            {
                return n > number && n % number == 0;
            }
        });
    }
});

1

यह सबसे सुरुचिपूर्ण है जो मैं छोटी सूचना पर सोच सकता हूं।

ArrayList generatePrimes(int numberToGenerate)
{
    ArrayList rez = new ArrayList();

    rez.Add(2);
    rez.Add(3);

    for(int i = 5; rez.Count <= numberToGenerate; i+=2)
    {
        bool prime = true;
        for (int j = 2; j < Math.Sqrt(i); j++)
        {
            if (i % j == 0)
            {
                    prime = false;
                    break;
            }
        }
        if (prime) rez.Add(i);
    }

    return rez;
}

आशा है कि यह आपको एक विचार देने में मदद करेगा। मुझे यकीन है कि यह अनुकूलित किया जा सकता है, हालांकि यह आपको एक विचार देना चाहिए कि आपके संस्करण को और अधिक सुरुचिपूर्ण कैसे बनाया जा सकता है।

संपादित करें: जैसा कि टिप्पणियों में नोट किया गया है कि यह एल्गोरिथ्म वास्तव में नंबरटोगेनरेट <के लिए गलत मान लौटाता है। 2. मैं केवल यह बताना चाहता हूं, कि मैं प्राइम नंबर जेनरेट करने के लिए उसे एक शानदार तरीका पोस्ट करने की कोशिश नहीं कर रहा था (हेनरी के जवाब को देखें) मैं स्पष्ट रूप से इंगित कर रहा था कि उनकी पद्धति को और अधिक सुरुचिपूर्ण कैसे बनाया जा सकता है।


3
यह संख्या नंबर 2 के लिए गलत परिणाम देता है <2
पीटर स्मिट

यह सच है, हालांकि मैं एक एल्गोरिथ्म नहीं डिजाइन कर रहा था, मैं सिर्फ उसे दिखा रहा था कि कैसे उसके तरीके को और अधिक सुरुचिपूर्ण बनाया जा सकता है। तो यह संस्करण भी उतना ही गलत है जितना कि शुरुआती सवाल।
डेविड बूजक

1
यह मेरे लिए नहीं था कि यह n = 1 के लिए टूट गया था। मैंने सवाल को थोड़ा बदल दिया ताकि फ़ंक्शन को केवल n> 1 :-) के लिए काम करना पड़े
डेविड जॉनस्टोन

यह प्राइम नंबर के रूप में प्रिम्स के वर्गों को स्वीकार करता है।
नेस

1

कार्यात्मक जावा में स्ट्रीम-आधारित प्रोग्रामिंग का उपयोग करते हुए , मैं निम्नलिखित के साथ आया। प्रकार Naturalअनिवार्य रूप से एक BigInteger> = 0 है।

public static Stream<Natural> sieve(final Stream<Natural> xs)
{ return cons(xs.head(), new P1<Stream<Natural>>()
  { public Stream<Natural> _1()
    { return sieve(xs.tail()._1()
                   .filter($(naturalOrd.equal().eq(ZERO))
                           .o(mod.f(xs.head())))); }}); }

public static final Stream<Natural> primes
  = sieve(forever(naturalEnumerator, natural(2).some()));

अब आपके पास एक मूल्य है, जिसे आप चारों ओर ले जा सकते हैं, जो कि अपराधों की एक अनंत धारा है। आप इस तरह की चीजें कर सकते हैं:

// Take the first n primes
Stream<Natural> nprimes = primes.take(n);

// Get the millionth prime
Natural mprime = primes.index(1000000);

// Get all primes less than n
Stream<Natural> pltn = primes.takeWhile(naturalOrd.lessThan(n));

छलनी का स्पष्टीकरण:

  1. तर्क स्ट्रीम में पहले नंबर को प्राइम मान लें और इसे रिटर्न स्ट्रीम के सामने रखें। रिटर्न स्ट्रीम के बाकी हिस्सों को केवल मांगे जाने पर उत्पादित किया जाना है।
  2. यदि कोई शेष धारा के लिए कहता है, तो बाकी तर्क धारा पर छलनी डालें, पहली संख्या से विभाज्य संख्याओं को छानकर (शेष भाग शून्य है)।

आपको निम्नलिखित आयात करने की आवश्यकता है:

import fj.P1;
import static fj.FW.$;
import static fj.data.Enumerator.naturalEnumerator;
import fj.data.Natural;
import static fj.data.Natural.*;
import fj.data.Stream;
import static fj.data.Stream.*;
import static fj.pre.Ord.naturalOrd;

1

मुझे व्यक्तिगत रूप से लगता है कि यह काफी छोटा और स्वच्छ (जावा) कार्यान्वयन है:

static ArrayList<Integer> getPrimes(int numPrimes) {
    ArrayList<Integer> primes = new ArrayList<Integer>(numPrimes);
    int n = 2;
    while (primes.size() < numPrimes) {
        while (!isPrime(n)) { n++; }
        primes.add(n);
        n++;
    }
    return primes;
}

static boolean isPrime(int n) {
    if (n < 2) { return false; }
    if (n == 2) { return true; }
    if (n % 2 == 0) { return false; }
    int d = 3;
    while (d * d <= n) {
        if (n % d == 0) { return false; }
        d += 2;
    }
    return true;
}

1

इस LINQ क्वेरी को आज़माएं, यह अभाज्य संख्याएँ उत्पन्न करता है जैसा कि आप उम्मीद करते हैं

        var NoOfPrimes= 5;
        var GeneratedPrime = Enumerable.Range(1, int.MaxValue)
          .Where(x =>
            {
                 return (x==1)? false:
                        !Enumerable.Range(1, (int)Math.Sqrt(x))
                        .Any(z => (x % z == 0 && x != z && z != 1));
            }).Select(no => no).TakeWhile((val, idx) => idx <= NoOfPrimes-1).ToList();

1
// Create a test range
IEnumerable<int> range = Enumerable.Range(3, 50 - 3);

// Sequential prime number generator
var primes_ = from n in range
     let w = (int)Math.Sqrt(n)
     where Enumerable.Range(2, w).All((i) => n % i > 0)
     select n;

// Note sequence of output:
// 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47,
foreach (var p in primes_)
    Trace.Write(p + ", ");
Trace.WriteLine("");

0

यहाँ एक अजगर कोड उदाहरण है जो दो मिलियन से नीचे के सभी अपराधों के योग को प्रिंट करता है:

from math import *

limit = 2000000
sievebound = (limit - 1) / 2
# sieve only odd numbers to save memory
# the ith element corresponds to the odd number 2*i+1
sieve = [False for n in xrange(1, sievebound + 1)]
crosslimit = (int(ceil(sqrt(limit))) - 1) / 2
for i in xrange(1, crosslimit):
    if not sieve[i]:
        # if p == 2*i + 1, then
        #   p**2 == 4*(i**2) + 4*i + 1
        #        == 2*i * (i + 1)
        for j in xrange(2*i * (i + 1), sievebound, 2*i + 1):
            sieve[j] = True
sum = 2
for i in xrange(1, sievebound):
    if not sieve[i]:
        sum = sum + (2*i+1)
print sum

0

सबसे सरल तरीका परीक्षण और त्रुटि है: आप कोशिश करते हैं कि 2 और n-1 के बीच कोई भी संख्या आपके उम्मीदवार को n विभाजित करती है।
पहले शॉर्टकट निश्चित रूप से एक हैं) आपको केवल विषम संख्या की जांच करनी है, और b) आप केवल sqrt (n) तक के डिवाइडर की जांच करने के लिए हवलदार हैं।

आपके मामले में, जहाँ आप इस प्रक्रिया में पिछले सभी अपराधों को भी उत्पन्न करते हैं, आपको केवल यह जाँचना है कि आपकी सूची में कोई भी वर्ग, sqrt (n) तक, n को विभाजित करता है या नहीं।
आप अपने पैसे के लिए प्राप्त कर सकते हैं सबसे तेज होना चाहिए :-)


ओके को संपादित करें , कोड, आपने इसके लिए कहा। लेकिन मैं आपको चेतावनी दे रहा हूं :-), यह 5 मिनट का त्वरित और गंदा डेल्फी कोड है:

procedure TForm1.Button1Click(Sender: TObject);
const
  N = 100;
var
  PrimeList: TList;
  I, J, SqrtP: Integer;
  Divides: Boolean;
begin
  PrimeList := TList.Create;
  for I := 2 to N do begin
    SqrtP := Ceil(Sqrt(I));
    J := 0;
    Divides := False;
    while (not Divides) and (J < PrimeList.Count) 
                        and (Integer(PrimeList[J]) <= SqrtP) do begin
      Divides := ( I mod Integer(PrimeList[J]) = 0 );
      inc(J);
    end;
    if not Divides then
      PrimeList.Add(Pointer(I));
  end;
  // display results
  for I := 0 to PrimeList.Count - 1 do
    ListBox1.Items.Add(IntToStr(Integer(PrimeList[I])));
  PrimeList.Free;
end;

1
और आप इसे कोड में कैसे व्यक्त करते हैं? :-)
डेविड जॉनस्टोन

0

पहले 100 अभाज्य संख्याओं का पता लगाने के लिए, निम्नलिखित जावा कोड पर विचार किया जा सकता है।

int num = 2;
int i, count;
int nPrimeCount = 0;
int primeCount = 0;

    do
    {

        for (i = 2; i <num; i++)
        {

             int n = num % i;

             if (n == 0) {

             nPrimeCount++;
         //  System.out.println(nPrimeCount + " " + "Non-Prime Number is: " + num);

             num++;
             break;

             }
       }

                if (i == num) {

                    primeCount++;

                    System.out.println(primeCount + " " + "Prime number is: " + num);
                    num++;
                }


     }while (primeCount<100);

0

मुझे विकी के साथ "एटकी की छलनी" के पहले पढ़ने से यह मिला, साथ ही कुछ पूर्व सोचा जो मैंने इसे दिया है - मैं खरोंच से कोडिंग में बहुत समय बिताता हूं और अपने कंपाइलर की तरह महत्वपूर्ण होने वाले लोगों पर पूरी तरह से शून्य हो जाता हूं, बहुत सुस्त कोडिंग शैली + मैंने कोड को चलाने का पहला प्रयास भी नहीं किया है ... मैंने जो भी उपयोग करना सीखा है उनमें से कई यहाँ हैं, बस पढ़ते हैं और रोते हैं, जो आप प्राप्त कर सकते हैं।

किसी भी उपयोग से पहले वास्तव में यह सब परीक्षण करने के लिए बिल्कुल और पूरी तरह से सुनिश्चित करें, यह सुनिश्चित करने के लिए कि यह किसी को भी न दिखाएं - यह विचारों को पढ़ने और विचार करने के लिए है। मुझे प्राइमलिटी टूल को काम करने की आवश्यकता है इसलिए यह वह जगह है जहां मैं हर बार काम शुरू करने के लिए कुछ काम करता हूं।

एक साफ संकलन प्राप्त करें, फिर दूर करना शुरू करें जो दोषपूर्ण है - मेरे पास लगभग 108 मिलियन कीस्ट्रोक्स हैं जो इसे इस तरह से कर रहे हैं, ... जो आप कर सकते हैं उसका उपयोग करें।

मैं कल अपने संस्करण पर काम करूंगा।

package demo;
// This code is a discussion of an opinion in a technical forum.
// It's use as a basis for further work is not prohibited.
import java.util.Arrays;
import java.util.HashSet;
import java.util.ArrayList;
import java.security.GeneralSecurityException;

/**
 * May we start by ignores any numbers divisible by two, three, or five
 * and eliminate from algorithm 3, 5, 7, 11, 13, 17, 19 completely - as
 * these may be done by hand. Then, with some thought we can completely
 * prove to certainty that no number larger than square-root the number
 * can possibly be a candidate prime.
 */

public class PrimeGenerator<T>
{
    //
    Integer HOW_MANY;
    HashSet<Integer>hashSet=new HashSet<Integer>();
    static final java.lang.String LINE_SEPARATOR
       =
       new java.lang.String(java.lang.System.getProperty("line.separator"));//
    //
    PrimeGenerator(Integer howMany) throws GeneralSecurityException
    {
        if(howMany.intValue() < 20)
        {
            throw new GeneralSecurityException("I'm insecure.");
        }
        else
        {
            this.HOW_MANY=howMany;
        }
    }
    // Let us then take from the rich literature readily 
    // available on primes and discount
    // time-wasters to the extent possible, utilizing the modulo operator to obtain some
    // faster operations.
    //
    // Numbers with modulo sixty remainder in these lists are known to be composite.
    //
    final HashSet<Integer> fillArray() throws GeneralSecurityException
    {
        // All numbers with modulo-sixty remainder in this list are not prime.
        int[]list1=new int[]{0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,
        32,34,36,38,40,42,44,46,48,50,52,54,56,58};        //
        for(int nextInt:list1)
        {
            if(hashSet.add(new Integer(nextInt)))
            {
                continue;
            }
            else
            {
                throw new GeneralSecurityException("list1");//
            }
        }
        // All numbers with modulo-sixty remainder in this list are  are
        // divisible by three and not prime.
        int[]list2=new int[]{3,9,15,21,27,33,39,45,51,57};
        //
        for(int nextInt:list2)
        {
            if(hashSet.add(new Integer(nextInt)))
            {
                continue;
            }
            else
            {
                throw new GeneralSecurityException("list2");//
            }
        }
        // All numbers with modulo-sixty remainder in this list are
        // divisible by five and not prime. not prime.
        int[]list3=new int[]{5,25,35,55};
        //
        for(int nextInt:list3)
        {
            if(hashSet.add(new Integer(nextInt)))
            {
                continue;
            }
            else
            {
                throw new GeneralSecurityException("list3");//
            }
        }
        // All numbers with modulo-sixty remainder in
        // this list have a modulo-four remainder of 1.
        // What that means, I have neither clue nor guess - I got all this from
        int[]list4=new int[]{1,13,17,29,37,41,49,53};
        //
        for(int nextInt:list4)
        {
            if(hashSet.add(new Integer(nextInt)))
            {
                continue;
            }
            else
            {
                throw new GeneralSecurityException("list4");//
            }
        }
        Integer lowerBound=new Integer(19);// duh
        Double upperStartingPoint=new Double(Math.ceil(Math.sqrt(Integer.MAX_VALUE)));//
        int upperBound=upperStartingPoint.intValue();//
        HashSet<Integer> resultSet=new HashSet<Integer>();
        // use a loop.
        do
        {
            // One of those one liners, whole program here:
            int aModulo=upperBound % 60;
            if(this.hashSet.contains(new Integer(aModulo)))
            {
                continue;
            }
            else
            {
                resultSet.add(new Integer(aModulo));//
            }
        }
        while(--upperBound > 20);
        // this as an operator here is useful later in your work.
        return resultSet;
    }
    // Test harness ....
    public static void main(java.lang.String[] args)
    {
        return;
    }
}
//eof

0

इस कोड को आज़माएं।

protected bool isPrimeNubmer(int n)
    {
        if (n % 2 == 0)
            return false;
        else
        {
            int j = 3;
            int k = (n + 1) / 2 ;

            while (j <= k)
            {
                if (n % j == 0)
                    return false;
                j = j + 2;
            }
            return true;
        }
    }
    protected void btn_primeNumbers_Click(object sender, EventArgs e)
    {
        string time = "";
        lbl_message.Text = string.Empty;
        int num;

        StringBuilder builder = new StringBuilder();

        builder.Append("<table><tr>");
        if (int.TryParse(tb_number.Text, out num))
        {
            if (num < 0)
                lbl_message.Text = "Please enter a number greater than or equal to 0.";
            else
            {
                int count = 1;
                int number = 0;
                int cols = 11;

                var watch = Stopwatch.StartNew();

                while (count <= num)
                {
                    if (isPrimeNubmer(number))
                    {
                        if (cols > 0)
                        {
                            builder.Append("<td>" + count + " - " + number + "</td>");
                        }
                        else
                        {
                            builder.Append("</tr><tr><td>" + count + " - " + number + "</td>");
                            cols = 11;
                        }
                        count++;
                        number++;
                        cols--;
                    }
                    else
                        number++;
                }
                builder.Append("</table>");
                watch.Stop();
                var elapsedms = watch.ElapsedMilliseconds;
                double seconds = elapsedms / 1000;
                time = seconds.ToString();
                lbl_message.Text = builder.ToString();
                lbl_time.Text = time;
            }
        }
        else
            lbl_message.Text = "Please enter a numberic number.";

        lbl_time.Text = time;

        tb_number.Text = "";
        tb_number.Focus();
    }

यहाँ aspx कोड है।

<form id="form1" runat="server">
    <div>
        <p>Please enter a number: <asp:TextBox ID="tb_number" runat="server"></asp:TextBox></p>

        <p><asp:Button ID="btn_primeNumbers" runat="server" Text="Show Prime Numbers" OnClick="btn_primeNumbers_Click" />
        </p>
        <p><asp:Label ID="lbl_time" runat="server"></asp:Label></p>
        <p><asp:Label ID="lbl_message" runat="server"></asp:Label></p>
    </div>
</form>

परिणाम: 10000 प्राइम नंबर एक सेकंड से भी कम समय में

63 सेकंड में 100000 प्राइम नंबर

पहले 100 अभाज्य संख्याओं का स्क्रीनशॉट यहाँ छवि विवरण दर्ज करें


1
इसे आज़माते हुए, मैं इसकी प्रभावशीलता और रिज़्यूटल की प्रस्तुति का अनुमान लगा सकता हूं: कृपया इसकी लालित्य पर बहस करें।
ग्रेबर्ड

परिणाम की स्टाइलिंग एक जोड़ा हिस्सा है। मुझे प्राइम नंबर के रूप में सही / गलत रिटर्न के लिए एल्गोरिथ्म पर चर्चा करने दें। n% 2 संख्याओं के आधे को समाप्त कर देगा क्योंकि यहां तक ​​कि संख्या हमेशा विभाज्य होती है। 2. दूसरे कोड में, मैं केवल विषम संख्याओं से विभाजित कर रहा हूं, दो से विभाज्य बढ़ रहा है (इसलिए अगला विभाज्य भी विषम है) उस संख्या का आधा भाग जो प्रमुख है या नहीं। क्यों आधा, समय बर्बाद नहीं करने के लिए क्योंकि यह हमें अंश में जवाब देगा।
रिज़

log10 (63) ~ = 1.8, अर्थात आपका डेटा n ^ 1.8 की वृद्धि दर दर्शाता है । यह बहुत धीमी है; एराटोस्थनीज कार्यान्वयन की इष्टतम छलनी ~ n ^ 1.01..1.05; इष्टतम परीक्षण विभाजन ~ n ^ 1.35..1.45। आपका isPrimeNubmerवास्तव में सबॉप्टीमल ट्रिल डिवीजन को लागू करता है; जब आप अधिक प्राइम उत्पन्न करने की कोशिश करेंगे तो इसका एसिम्प्टोटाइक्स लगभग n ^ 2 (या इससे भी ऊपर) तक बिगड़ जाएगा।
विल नेस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.