2013-04-20 45 views
6

Meine Frage bezieht sich Mit Logik:den folgenden Code in einer switch-Anweisung

public static void main(String[] args) { 

    // Find Prime Numbers from 0 to 100 
    int i; 
    for (i=2; i <= 100; i++) { 
     int j = 2; 
     boolean iPrime = true; 

     //The following line gives incorrect results, but should execute faster 
     // while ((iPrime = true) && (j < (i/2 + 1))) { 
     //The following line gives correct results but performs un-necessary operations 
     //by continuing to calculate after the number is found to be "not prime" 
     while (j < (i/2 + 1)) { 

      j++; 
      if ((i % j) == 0) { 
       iPrime = false; 
       //System.out.println(j + " is a factor of " + i); 
      } 
     } 
     if (iPrime) { 
      System.out.println(i + " is a prime number!"); 
     } 
    } 
} 

Jetzt, da ich in dem Code kommentiert habe, was ich versuche, ist eine schnellere Ausführung meines Programms zu erreichen, indem Sie die while-Schleife nur ausführen, wenn iPrime = true ist. 50% der Zahlen sind durch 2 teilbar. Sobald dies festgestellt ist, können die Berechnungen beendet werden.

Ich mache dieses Projekt als Teil eines ‚Beispiel‘ Anfänger aus einem Buch, ich versuche tatsächlich 1000000 zu berechnen so schnell wie möglich, nur für meinen eigenen „extra credit“ ...

Ich lese, dass der "Kurzschluss" und "Operator" & & nur die zweite Hälfte der Aussage wertet, wenn die erste Hälfte wahr ist, wenn es falsch ist, werden die beiden nicht gegeneinander ausgewertet (speichern CPU)

Und es wird auch die Schleife verlassen, die noch mehr CPU sparen wird ...

Aber für etwas Der Grund, es funktioniert nicht richtig! Ich habe mehr System.out.println() Anweisungen überall, auflisten, was "iPrime" ist - und die Ausgabe ist seltsam ... Es schaltet iPrime ein und aus und wertet jede Zahl aus, die ich nicht verstehen kann.

+0

Danke für die Hilfe aller! Es war so offensichtlich, sobald ich Ihre Antworten bekam, und das Sieb von Eratosthenes wäre in der Tat ein viel besserer Algorithmus! Ich kann nur eine Antwort wählen, aber Sie waren alle genauso hilfreich, danke! – JBainesy

Antwort

7

if((iPrime = true) && ...) sollte if((iPrime) && ...) sein.

Dadurch isPrime = true dann sind Sie Zuordnung wahr zu isPrime und nicht Vergleich seinen Wert true.

Sie können auch sehen wollen this besser zu verstehen, was im Code passiert:

Zur Laufzeit das Ergebnis der Zuweisungsausdruck ist der Wert von die Variable nach der Zuordnung erfolgte. Das Ergebnis eines Zuweisungsausdrucks ist selbst keine Variable. So

, wenn Sie den = Operator statt == (der entfernt wird, wenn Sie etwas zu true vergleichen - statt if(someBoolean == true) Schreiben Sie einfach schreiben if(someBoolean)) Sie erfüllen tatsächlich die Bedingung, immer!

+1

JA! Das ist jetzt klar! Ich erinnere mich daran zu denken, als ich zum ersten Mal von den =/== Operatoren gelesen habe, dass sie mich austricksen würden! Schätze die Hilfe, ich werde von nun an auf diese Falle achten! – JBainesy

+0

Ich bin froh, dass es geholfen hat, viel Glück :) – Maroun

4

einfach = in == ändern, das heißt,

ändern
while ((iPrime = true) && (j < (i/2 + 1))) 

in

while ((iPrime == true) && (j < (i/2 + 1))) 

ein Full-Code mit einer besseren Leistung

public static void main(String[] args) { 
    // Find Prime Numbers from 0 to 100 
    System.out.println(2 + " is a prime number!"); 
    for (int i = 3; i <= 100; i += 2) { 
     boolean isPrime = true; 
     for (int j = 3; j * j <= i; j += 2) { 
      if ((i % j) == 0) { 
       isPrime = false; 
       break; 
      } 
     } 
     if (isPrime) { 
      System.out.println(i + " is a prime number!"); 
     } 
    } 
} 

Die schnellste Methode, die ich von ist denken kann Sieve of Eratosthenes.

+0

Oder 'while (iPrime && (j <(i/2 + 1)))' –

+1

'someBoolean == true'? "Ja wirklich?" –

+0

@AchintyaJha also die Veröffentlichung '1 == 1' ist gut, oder? –

1

johnchen902/Maroun Maroun haben Ihren Bugfix; Darüber hinaus ist eine Optimierung Sie ausführen können

System.out.println("2 is a prime number!"); // the for loop won't detect 2 anymore 
for (i=3; i <= 100; i+=2) { 

Auch anstelle der Modulo-Operator mit allen vorhergehenden ungeraden Zahlen auf einer Reihe von durchführen, um zu sehen, ob es eine Primzahl ist, können Sie den Modulo-Operator auf eine Reihe durchführen mit allen vorhergehenden Primes, um zu sehen, ob es prim ist - zum Beispiel speichern Sie die Primzahlen, die Sie in einer ArrayList finden, und durchlaufen Sie die Liste in Ihrem Haupttest.

Und für einen sehr CPU-effizient (aber weniger Raum effizient) Algorithmus, die Sieve of Eratosthenes

1

verwenden Zum einem Code zum Ausführen fand ich, dass es 4 als Primzahl zeigt, die nicht korrekt ist. Der Grund ist der Standort Ihrer j ++ Zeile. Sie sollten Ihre while-Schleife ändern:

while (j < (i/2 + 1)) { 
       if ((i % j) == 0) { 
        iPrime = false; 

        //System.out.println(j + " is a factor of " + i); 
        break; 
       } 
       j++; 
      } 

zum zweiten Teil Umzug auf, möchten Sie zusätzliche Berechnung vermeiden, wenn Sie festgestellt haben, dass die Zahl keine Primzahl ist. Sie können hierzu die break-Anweisung wie im obigen Code verwenden.

Der kommentierte Teil funktioniert nicht, weil Sie eine Zuordnung anstelle von Gleichheitsvergleich haben.

Verwandte Themen