26.* Napisz program, w którym zdefiniowana jest jedna zmienna będąca liczbą naturalną, a program
dokonuje jej rozkładu na czynniki pierwsze i wyświetla wynik na ekranie.
Przykładowy wynik działania programu:
Wybrana liczba: 56
Rozkład: 56 = 2^3 + 7^1
Wersja łatwiejsza: dokonaj rozkładu na czynniki pierwsze i wyświetl wynik na ekranie w
dowolny czytelny sposób (nie musi być to tak ładnie zapisane jak powyżej).
int liczba = 56;
System.out.println("Wybrana liczba: "+liczba);
System.out.print("Rozklad: "+liczba+"=");
for(int czynnik=1; czynnik <= liczba; czynnik++)
{
if(czynnik==1)
{
continue;
}
else if(liczba%czynnik==0) // dzielnik
{
if(czynnik==liczba)
{
System.out.print(czynnik); // ostatni dzielnik jest wypisywany bez znaku "*"
}
else
{
System.out.print(czynnik+"*"); // pozostale dzielniki sa wypisywane ze znakiem "*"
}
liczba = liczba / czynnik;
}
}
Jak mógłbym zoptymalizować ten program? Nie wiem jak powrócić, żeby liczyło ponownie zmienną czynnik od 1, gdy znajdzie jakiś czynnik inny niż 1. Póki co dla liczby 56 wypisuje 2*4*7. W sumie to pytanie czy w ogóle da się to zrobić z pętlą for?
Zrobiłem to z pętlą while i mam nadzieję, że tak jest ok (na podstawie tego, co sprawdziłem):
int liczba = 162;
System.out.println("Wybrana liczba: "+liczba);
System.out.print("Rozklad: "+liczba+"=");
int czynnik=2;
while(czynnik <= liczba)
{
if(liczba%czynnik==0) // dzielnik
{
if(czynnik==liczba)
{
System.out.print(czynnik); // ostatni dzielnik jest wypisywany bez znaku "*"
}
else
{
System.out.print(czynnik+"*"); // pozostale dzielniki sa wypisywane ze znakiem "*"
}
liczba = liczba / czynnik;
}
else
{
czynnik++;
}
}
A dlaczego tam na końcu jest czynnik--; ?
Właśnie dlatego, że używamy pętli for zamiast while. W pętli for na końcu jej obiegu zawsze wykonuje się instrukcja kroku, ale my byśmy chcieli, aby niekiedy się nie wykonywała - stąd dajemy ten czynnik--. W pętli while sami musimy o tej instrukcji pamiętac we wnętrzu pętli, dlatego w sumie użycie while było może bardziej naturalne w tym przypadku.
1 - Próbuję to zrozumieć na przykładzie liczby 15, ale nie wiem właściwie kiedy program ma się zakończyć (najpierw 2 nie jest dzielnikiem to sprawdza 3, która jest dzielnikiem, więc ją wypisuje i ustawia liczbę na 5, potem ponownie sprawdza 3, które już nie jest dzielnikiem piątki, tak samo 4 też nie i 5 jest dzielnikiem 5, więc liczba = 5/5 = 1 i teraz liczba = 1 < czynnik = 5). Czy to działa w ten sposób?
2 - Czyli pętla while ma automatycznie wbudowaną instrukcję w tym przypadku czynnik--?
1 - hmm, ale to Ty sam napisałeś ten kod (w odpowiedziach jest to inaczej robione), więc chyba wiesz jak to działa, bo musiałeś się kierować jakąś logiką przy pisaniu tego kodu :D ale tak, tak to działa ;)
2 - nie, pętla while nie ma automatycznie wbudowanej instrukcji czynnik++ ;)
Ja dalej nie rozumiem dlaczego tam jest czynnik-- w sposobie z petla for, czy mógłby Pan to wyjaśnić na przykładzie jakiejś liczby?
Zauważ, że w pętli while, robimy czynnik++ tylko wtedy gdy warunek if(liczba%czynnik==0) nie zostanie spełniony. Jeśli jest spełniony, to kolejny obieg pętli wykonuje się dla ciągle tej samej wartości czynnik.
Natomiast w przypadku użycia pętli for z automatu wykonuje się operacja czynnik++ na koniec każdego obiegu pętli. A patrząc na pętlę while to widzimy, że jeśli wspomniany warunek if(liczba%czynnik==0) będzie spełniony, to nie chcemy, żeby taka operacja się wykonywała. Więc żeby skompensować to czynnik++, które i tak się na koniec wykona dajemy tutaj właśnie czynnik--. Wtedy w kolejnym obiegu pętli ostatecznie czynnik będzie bez zmian.
Czy w takim razie nie można po prostu w zapisie pętli for usunąć czynnik++ , aby nie musieć pisać tego czynnik-- potem?
Czyli jak liczba nie jest podzielna przez dany czynnik to program pomija if i else i robi po prostu czynnik++?
No w zasadzie można by tak zrobić.
Tak.
Tak, jest ok, i oczywiście da się to zrobić z forem, np. tak:
for (czynnik = 2; czynnik <= liczba2; czynnik++)
{
if(liczba2%czynnik==0) // dzielnik
{
if(czynnik==liczba2)
{
System.out.print(czynnik); // ostatni dzielnik jest wypisywany bez znaku "*"
}
else
{
System.out.print(czynnik+"*"); // pozostale dzielniki sa wypisywane ze znakiem "*"
}
liczba2 = liczba2 / czynnik;
czynnik--;
}
}