Artur 111 wyśw. 04-07-2025 15:55

Praca domowa 2 zad 26

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++;
            }
        }


Programowanie Dodaj post do ulubionych Poproś o pomoc
s.gugula 06-07-2025 11:18

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--;

            }


        }


Artur 06-07-2025 13:53

A dlaczego tam na końcu jest czynnik--; ?


s.gugula 06-07-2025 23:19

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.


Artur 07-07-2025 11:06

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--?


s.gugula 09-07-2025 00:11

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++ ;)


Artur 09-07-2025 14:11

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?


s.gugula 10-07-2025 14:44

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.


Artur 10-07-2025 15:34

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++?


s.gugula 11-07-2025 20:58

No w zasadzie można by tak zrobić.

Tak.