Για να ελέγξουμε αν ένας αριθμός είναι πρώτος, δεν είναι ανάγκη να ελέγξουμε
for ( i=2; i< num/2; ++i ) {
if ( num % i ) {
not_prime();
}
}
Μπορούμε να ελέγξουμε απλά μέχρι την τετραγωνική ρίζα του αριθμού
for ( i=2; i<= sqrt (num); ++i ) .......
Απόδειξη :
Αν ένας αριθμός δεν είναι πρώτος, τότε αναλύεται σε δύο άλλους αριθμούς ( εξ ορισμού ).
Αν και οι δύο ήταν μεγαλύτεροι από την τετραγωνική του ρίζα, τότε το γινόμενό τους θα ήταν μεγαλύτερο του αριθμού
- καραάτοπο. Άρα σίγουρα ο μικρότερος από τους δύο θα είναι μικρότερος ή ίσος της τετραγωνικής ρίζας του ζητούμενου αριθμού.
Έτσι με μόνο αυτή τη βελτίωση, η πολυπλοκότητα του αλγορίθμου πέφτει από Ν^2 σε Ν*sqrt(N).
Όμως και πάλι, δεν είναι ανάγκη να ελέγχουμε με κάθε αριθμό στο διάστημα [2,sqrt(N)] αλλά μόνο με τους πρώτους αριθμούς εδώ μέσα ( ο μικρός αριθμός για τον οποίο μιλήσαμε πιο πάνω ή πρώτος είναι, ή αν δεν είναι, αναλύεται σε πρώτους ( πάλι εξ`ορισμού ), άρα αν κάποιος αριθμός σε αυτό το διάστημα διαιρεί τον ζητούμενό μας σε, τότε σίγουρα κάποιος πρώτος τον διαιρεί ). Επομένως μια ακόμα μικρή βελτίωση θα είναι να προϋπολογίσουμε όλους τους πρώτους μέχρι τη ρίζα του maxN και μετά να ελέγχουμε κάθε φορά με αυτούς ( μέχρι κάποιος από αυτούς να ξεπεράσει την τετραγωνική ρίζα του ζητούμενου αριθμού μας για την ακρίβεια ).
Τελευταία βελτίωση, τους πρώτους αριθμούς μέχρι την τετραγωνική ρίζα του maxN, τους βρίσκουμε με κόσκινο του ερατοσθένη.
Πιο γρήγορη λύση, δεν ξέρω.
Υ.Γ.: Σε τεστ που έκανα στον υπολογιστή μου, να τρέχεις έναν έναν όλους τους αριθμούς μέχρι την ρίζα του ζητούμενου είναι κατά ελάχιστα πιο αργό ( τόσο ελάχιστο που δεν αξίζει να αλλάξεις αλγόριθμο σε διαγωνισμό ) από το κόσκινο του Ερατοσθένη, κι η μέθοδος που περιγράφω πιο πάνω ελάχιστα πιο γρήγορη από αυτές τις δύο, άρα πιο πολύ θεωρητικό ενδιαφέρον έχει, παρά πρακτικό.