Um die Primzahl einer Zahl zu prüfen, n würde man in erster Linie eine Schleife wie die folgende erwarten:
bool isPrime = true;
for(int i = 2; i < n; i++){
if(n%i == 0){
isPrime = false;
break;
}
}
Die obige Schleife funktioniert folgendermaßen: für eine gegebene 1 < i < n wird geprüft, ob n/i eine ganze Zahl ist (der Rest bleibt 0). Wenn es ein i gibt, für das n/i eine ganze Zahl ist, dann können wir sicher sein, dass n keine Primzahl ist, und die Schleife endet. Wenn für kein i n/i eine ganze Zahl ist, dann ist n eine Primzahl.
Wie bei jedem Algorithmus fragen wir: Können wir es besser machen?
Schauen wir uns an, was in der obigen Schleife vor sich geht.
Die Folge von i lautet: i = 2, 3, 4, ... , n-1
Und die Folge der ganzzahligen Prüfungen lautet: j = n/i, also n/2, n/3, n/4, ... , n/(n-1)
Wenn für einige i = a, n/a eine ganze Zahl ist, dann ist n/a = k (ganze Zahl)
oder n = ak, eindeutig n > k > 1 (wenn k = 1, dann a = n, aber i erreicht nie n; und wenn k = n, dann a = 1, aber i beginnt mit 2)
Außerdem ist n/k = a, und wie oben erwähnt, ist a ein Wert von i, also n > a > 1.
a und k sind also beide ganze Zahlen zwischen 1 und n (ausschließlich). Da i jede ganze Zahl in diesem Bereich erreicht, ist bei einer Iteration i = a und bei einer anderen Iteration i = k. Wenn der Primärtest von n für min(a,k) fehlschlägt, wird er auch für max(a,k) fehlschlagen. Wir brauchen also nur einen dieser beiden Fälle zu prüfen, es sei denn, min(a,k) = max(a,k) (dann reduzieren sich zwei Prüfungen auf eine), d.h. a = k , dann ist a*a = n, was a = sqrt(n) impliziert.
Mit anderen Worten: Wenn der Primzahltest von n für einige i >= sqrt(n) (d.h. max(a,k)) fehlschlägt, dann auch für einige i <= n (d.h. min(a,k)). Es würde also genügen, wenn wir den Test für i = 2 bis sqrt(n) durchführen.
51 Stimmen
Denn wenn
n = a*b
ya <= b
entoncesa*a <= a*b = n
.18 Stimmen
Zur Verdeutlichung: Das bedeutet, dass wir nur bis zu dem Zeitpunkt testen müssen, an dem
floor(sqrt(n))
.7 Stimmen
mathandmultimedia.com/2012/06/02/