2013-04-20 8 views
6

Moje pytanie związane jest z następującego kodu:Stosując logikę wewnątrz instrukcji switch

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!"); 
     } 
    } 
} 

Teraz, jak już zauważył w kodzie, co staram się osiągnąć to szybciej realizacja mojego programu poprzez wykonanie pętli "while" tylko wtedy, gdy iPrime = true. 50% liczb jest podzielnych przez 2, a więc po ustaleniu, obliczenia mogą się zatrzymać.

robię ten projekt jako część „przykład” dla początkujących z książką, faktycznie staram się obliczyć do 1000000 jak najszybciej po prostu dla własnej „ekstra kredytu” ...

czytałem, że „zwarcia«i»operator” & & ocenia tylko drugą połowę rachunku, jeśli pierwsza połowa jest prawdą, jeśli jest fałszywe, dwa nie są oceniane przed siebie (oszczędność CPU)

I to również zakończy pętlę, co pozwoli zaoszczędzić jeszcze więcej procesora ...

Ale dla som Powód, nie działa poprawnie! Dodałem więcej instrukcji System.out.println(), wymieniając czym jest "iPrime" - a wynik jest dziwny ... Włącza i wyłącza iPrime i ocenia każdy numer, którego nie rozumiem.

+0

Dzięki za pomoc wszystkich! To było takie oczywiste, gdy dostałem twoje odpowiedzi, a sito Eratostenesa byłoby znacznie lepszym algorytmem! Mogę wybrać tylko jedną odpowiedź, ale wszyscy byliście tak samo pomocni, dziękuję! – JBainesy

Odpowiedz

7

if((iPrime = true) && ...) powinien być if((iPrime) && ...).

Robiąc isPrime = true to jesteś przypisywania prawda do isPrime a nie porównując jego wartość true.

kupili także zobaczyć this aby lepiej zrozumieć to, co dzieje się w kodzie:

W czasie wykonywania wynikiem wyrażenia przypisania jest wartość zmienna po nastąpieniu cesji. Wynik wyrażenia przypisania przypisania nie jest zmienną.

Więc, kiedy użyć operatora = zamiast == (który jest usuwany, jeśli porównać coś true - zamiast pisać if(someBoolean == true) po prostu napisać if(someBoolean)), jesteś rzeczywiście spełniające warunek, zawsze!

+1

TAK! To jest teraz jasne! Pamiętam, że pomyślałem, kiedy po raz pierwszy przeczytałem o operatorach =/==, że mnie oszukają! Doceń pomoc, od tej chwili będę ostrożna! – JBainesy

+0

Cieszę się, że pomogło, powodzenia :) – Maroun

4

Wystarczy zmienić = do ==, czyli zmienić

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

do

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

A pełny kod z lepszej wydajności

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!"); 
     } 
    } 
} 

najszybszym sposobem mogę myśleć jest Sieve of Eratosthenes.

+0

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

+1

'someBoolean == true'? Naprawdę? –

+0

@AchintyaJha, więc zamieszczanie '1 == 1' jest dobre, prawda? –

1

johnchen902/Maroun Maroun mają poprawkę; Ponadto optymalizacja można wykonać jest

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

Ponadto, zamiast przeprowadzania operatora modulo na liczbę z wszystkich poprzednich numerach nieparzystych, aby zobaczyć, czy jest to pierwsze, można wykonywać operator modulo od szeregu z wszystkimi poprzednimi liczbami pierwszymi, aby zobaczyć, czy jest to pierwsze - na przykład przechowuj liczby pierwotne znalezione w tablicy ArrayList i przeglądaj listę w teście podstawowym.

I za bardzo (ale mniej przestrzeni wydajny algorytm) CPU-wydajny, użyj Sieve of Eratosthenes

1

Przede wszystkim na prowadzeniu kod Okazało się, że to pokazuje, 4 jako główny numer, który jest nieprawidłowy. Powodem jest lokalizacja twojej linii j ++. Należy zmienić pętli while jak:

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

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

Przechodząc do drugiej części, chcesz uniknąć dodatkowych obliczeń, gdy ustalono, że liczba nie jest liczbą pierwszą. Możesz użyć instrukcji break dla tego, jak w powyższym kodzie.

Skomentowana część nie działa, ponieważ masz przypisanie zamiast porównywania równości.