Liczby pierwsze

0

Witam.
Napisałem programik, który powinien dla liczb od 1 do 10000 dopisać TAK - jeżeli jest to liczba pierwsza lub NIE jeżeli jest to liczba złożona.
Niby wszystko działa. Program się kompiluje, wybiera dobrze liczby pierwsze, ale wyświetla mi liczby zaczynając od 3, omija 1 i 2.
Nie mogę znaleźć błędu.
Jeżeli ktoś miałby chwilkę i mi pomógł to byłbym wdzięczny.

public class LiczbyPierwszeSPOJ {
	public static void main(String[] args) {
		for (int n=1; n<100000; n++) {
			for (int i=2; i<n; i++) {
				int reszta = reszta(n, i);
				if (reszta != 0) {
					int j = n-1;
					if (i == j) {
						System.out.println(n + " " + reszta + " " + "TAK");
					}
					else
						continue;
				}
				else
					System.out.println(n + " " + reszta + " " + "NIE");
					break;
			}
		}	
	}
	
	public static int reszta(int liczba1, int liczba2) {
		int wynik = liczba1 / liczba2;
		int wynik2 = wynik * liczba2;
		int reszta = liczba1 - wynik2;
		return reszta;
	}
}

Tak wygląda wynik dla n<50:

3 1 TAK
4 0 NIE
5 1 TAK
6 0 NIE
7 1 TAK
8 0 NIE
9 0 NIE
10 0 NIE
11 1 TAK
12 0 NIE
13 1 TAK
14 0 NIE
15 0 NIE
16 0 NIE
17 1 TAK
18 0 NIE
19 1 TAK
20 0 NIE
21 0 NIE
22 0 NIE
23 1 TAK
24 0 NIE
25 0 NIE
26 0 NIE
27 0 NIE
28 0 NIE
29 1 TAK
30 0 NIE
31 1 TAK
32 0 NIE
33 0 NIE
34 0 NIE
35 0 NIE
36 0 NIE
37 1 TAK
38 0 NIE
39 0 NIE
40 0 NIE
41 1 TAK
42 0 NIE
43 1 TAK
44 0 NIE
45 0 NIE
46 0 NIE
47 1 TAK
48 0 NIE
49 0 NIE

P.s. Proszę tylko bez krzyków, uczę się javy od niedawna ;-)

0

o_O? Tam gdzie masz "continue" nie wypisujesz nic. A algorytm na spoju nie przejdzie czasowo, bo jest nieoptymalny.

1

cała Twoja funkcja "reszta" to operator modulo %

liczba1 % liczba2

zastosowałeś jakąś bardzo dziwną metodę wypisywania "TAK" na wyjście żeby się nie powtarzało
bo teraz masz dla 1:
i = 2
j = n - 1 = 1 - 1 = 0

2 != 0 więc nic nie wypisuje i idzie do następnej liczby
gdybyś użył debugera to wyłapałbyś to sto razy szybciej niż napisał post na forum...

jeśli nie chcesz żeby się coś powtarzało to wywal to poza pętlę zamiast pisać jakieś dziwne warunki
no i oczywiście omiń jeśli liczba nie jest pierwsza - pomoże ci w tym wydzielenie kodu do osobnej funkcji lub jakaś zmienna pomocnicza

zresztą ten kod i tak się nie nadaje - w tym zadaniu chodzi prawdopodobnie o wykorzystanie sita Eratostenesa
a co najmniej o liczenie tylko do dzielników nie większych niż pierwiastek liczby

0

Za bardzo tam namieszałeś. Mogłeś na przykład tak:

def isPrime(number):
    if number < 2:
        return False
    if number == 2:
        return True
    if number % 2 == 0:
        return False
    for divider in range(3, int(math.ceil(math.sqrt(number)) + 1), 2):
        if number % divider == 0:
            return False
    return True
0

Czy w tym kodzie wyżej nie będzie wypisywać za każdym razem True na końcu? Czyli jak liczba będzie pierwszą to wypisze:
True
natomiast jak będzie złożoną, to wypisze:
False
True

Nie wiem za bardzo właśnie jak zrobić to tak aby wypisywało mi się tylko raz NIE lub TAK, a nie przy każdym sprawdzeniu dzielnika mniejszego bądź równego pierwiastku liczby. Właśnie przez to tak namieszałem w pierwszym programie.

0
Vendetta napisał(a):

Czy w tym kodzie wyżej nie będzie wypisywać za każdym razem True na końcu? Czyli jak liczba będzie pierwszą to wypisze:
True
natomiast jak będzie złożoną, to wypisze:
False
True

Nie wiem za bardzo właśnie jak zrobić to tak aby wypisywało mi się tylko raz NIE lub TAK, a nie przy każdym sprawdzeniu dzielnika mniejszego bądź równego pierwiastku liczby. Właśnie przez to tak namieszałem w pierwszym programie.

return wychodzi z funkcji
może będzie o tym w następnym rozdziale

0

Tak wygląda nowa wersja programu na tą chwilę:

public class LiczbyPierwszeSPOJ {
	public static void main(String[] args) {
		
		for (int n=1; n<50; n++) {
			double pierwiastek = Math.sqrt(n); //wyliczanie pierwiastka ze sprawdzanej liczby
			if (pierwiastek == 1)
				System.out.println(n + " NIE"); // wypisanie wyniku dla liczby 1
			else {	
wyjscie:
				for (int i=2; i<=pierwiastek; i++) {
					double reszta = n % i; // wyliczanie reszty
					if (reszta == 0) {
						System.out.print(n + " NIE "); // wypisywanie dla liczby złożonej
						break wyjscie; //wyjście przy pierwszym trafionym dzielniku dającym resztę 0 (aby nie wypisywało NIE dla każdego dzielnika liczby)
					}
					else
						continue;
				}
				System.out.println(n +" TAK");
			}
		}
	}
}

A tak wygląda wynik:

1 NIE
2 TAK
3 TAK
4 NIE 4 TAK
5 TAK
6 NIE 6 TAK
7 TAK
8 NIE 8 TAK
9 NIE 9 TAK
10 NIE 10 TAK
11 TAK
12 NIE 12 TAK
13 TAK
14 NIE 14 TAK
15 NIE 15 TAK
16 NIE 16 TAK
17 TAK
18 NIE 18 TAK
19 TAK
20 NIE 20 TAK
21 NIE 21 TAK
22 NIE 22 TAK
23 TAK
24 NIE 24 TAK
25 NIE 25 TAK
26 NIE 26 TAK
27 NIE 27 TAK
28 NIE 28 TAK
29 TAK
30 NIE 30 TAK
31 TAK
32 NIE 32 TAK
33 NIE 33 TAK
34 NIE 34 TAK
35 NIE 35 TAK
36 NIE 36 TAK
37 TAK
38 NIE 38 TAK
39 NIE 39 TAK
40 NIE 40 TAK
41 TAK
42 NIE 42 TAK
43 TAK
44 NIE 44 TAK
45 NIE 45 TAK
46 NIE 46 TAK
47 TAK
48 NIE 48 TAK
49 NIE 49 TAK

Muszę się pozbyć tylko wyświetlania TAK przy każdej liczbie złożonej i już powinno być ok :) Pierwsza kolumna pokazuje prawidłowe wyniki.

0

Musiałbyś zapamiętywać, że już napisałeś 'NIE. Nie lubię break

public class LiczbyPierwsze {
    public static void main(String[] args) 
    {
 
                for (int n=1; n<=50; n++) 
                {
                    double pierwiastek = Math.sqrt(n); //wyliczanie pierwiastka ze sprawdzanej liczby
                    if (pierwiastek == 1)
                                System.out.println(n + " NIE"); // wypisanie wyniku dla liczby 1
                    else 
                    {
                        boolean isPrime = true;                     
                        int i = 2;
                        while (i<=pierwiastek && isPrime) 
                        {
                            double reszta = n % i; // wyliczanie reszty
                            if (reszta == 0) 
                            {
                                isPrime = false;
                                
                            }
                            i++;
                        }
                        if(isPrime)
                        {
                            System.out.println(n + " TAK");
                        }
                        else
                        {
                            System.out.println(n +" NIE");
                        }
                    }
                }
        }
}
0

a nie lepiej po prostu

 
if(pierwiastek == 1){
  System.out.println(n + " NIE");
  continue;
}

pozbywasz się niepotrzebnego else'a (kod ładniejszy). mało tego porównujesz ina z double. Czy nie będzie lepiej po prostu zrzutować double na inta? (tak utnie dane, ale w tym przypadku to nie ma znaczenia)

i co to jest to ;o?

break wyjscie;

zamiast wyświetlać "nie" w pętli zrób sobie zmienna boolean. Jeżeli jest true to wyświetl tak jeżeli jest false wyświetl nie (po za forem sprawdzającym)

EDIT. eh, mocno się spóźniłem. Tak to jest jak się robi kilka rzeczy na raz

0

Wziąłem pod uwagę Wasze porady i przerobiłem tak mój programik:

public class LiczbyPierwszeSPOJ {
	public static void main(String[] args) {
		
		for (int n=1; n<50; n++) {
			double pierwiastek = Math.sqrt(n);
			if (pierwiastek == 1) {
				System.out.println(n + " NIE");
				continue;
			}
			boolean zmienna = true;
				for (int i=2; i<=pierwiastek; i++) {
					double reszta = n % i;
					if (reszta == 0) {
						zmienna = false;
					}
				}
				if (zmienna)
					System.out.println(n + " TAK");
				else
					System.out.println(n + " NIE");
			
		}
	}
}

Wszystko działa jak należy. Bardzo Wam dziękuję za pomoc :)

0

U mnie pętla miała postać

while (i<=pierwiastek && isPrime)

po to by przerwać wykonywanie pętli po znalezieniu pierwszego dzielnika. Twoja pętla będzie się wykonywać dalej. Dla liczb z przedziału [1,50] nie ma to znaczenia, ale przy sprawdzaniu czy liczba 2 000 000 000 jest pierwsza ma znaczenie. Znajdziesz dzielnik równy 2, a potem będziesz jeszcze sprawdzał czy się nie dzieli przez 3,4,...,44721.

0

No tak, nie pomyślałem o tym. Twój kod jest dużo bardziej optymalny. Dzięki.

1 użytkowników online, w tym zalogowanych: 0, gości: 1