Artur 105 wyśw. 02-07-2025 18:50

Praca domowa 2 zad 13

13. Napisz program, w którym zdefiniowana jest początkowo zmienna typu całkowitego - ma być to
liczba naturalna.
a) program oblicza sumę wszystkich liczb naturalnych podzielnych przez 7 i mniejszych od danej
liczby
b) program oblicza ile jest wszystkich liczb naturalnych podzielnych przez 11 i mniejszych od danej
liczby
W jednym z przypadków użyj pętli while, a w innym pętli do-while.
Przykładowy wynik działania programu:
a) Wybrany limit: 46
Suma liczb podzielnych przez 7 mniejszych od 46: 147
b) Wybrany limit: 59
Liczb podzielnych przez 11 mniejszych od 59 jest: 5


        int limit=59;
        
        // a)
        System.out.println("Wybrany limit: "+limit);
        int suma = 0;
        for(int i = 1; i < limit; i++)
        {
            if(i%7==0)
            {
                suma += i; // suma = suma + i;
            }
        }
        System.out.println("Suma liczb podzielnych przez 7 mniejszych od "+limit+": "+suma);
        
        // b) 
        int liczba = 0;
        for(int j = 1; j < limit; j++)
        {
            if(j%11==0)
            {
                liczba++; 
            }
        }
        System.out.println("Liczb podzielnych przez 11 mniejszych od "+limit+": "+liczba);


1 - Czy ten kod też jest w pełni poprawny (Pomijając polecenie, którego nie doczytałem: W jednym z przypadków użyj pętli while, a w innym pętli do-while.)?

2 - Czy należy tu przyjąć zero jako liczbę naturalną?


SPOSOB Z WHILE/ DO WHILE:

  int limit=5;
        
        // a)
        
        System.out.println("Wybrany limit: "+limit);
        int suma = 0;
        int i = 0;
        while(i < limit)
        {
            i++;
            if(i%7==0)
            {
                suma += i; // suma = suma + i;
            }
        }
        System.out.println("Suma liczb podzielnych przez 7 mniejszych od "+limit+": "+suma);
        
        // b)
        int liczba = 0;
        int j = 0;
        do 
        {
            j++;
            if(j%11==0)
            {
                liczba++; 
            }
        }
            while(j < limit);
        System.out.println("Liczb podzielnych przez 11 mniejszych od "+limit+": "+liczba);


3 - Ja rozpoczynam od j = 0, a w kryteriach rozpoczyna się od -1 (przykład b), a jednak mimo to wynik wychodzi mi prawidłowy, gdy limit!=wielokrotność 11, a gdy limit==wielokrotność 11 to liczba jest o 1 za duża i nie wiem co tutaj można zmienić, bo jak z kolei dam j=-1 to wtedy, gdy limit!=wielokrotność 11 będzie błędny.


Programowanie Dodaj post do ulubionych Poproś o pomoc
s.gugula 02-07-2025 21:43

1 - tak, wygląda ok.

2 - a to już nie zostało doprecyzowane w treści - można więc sobie przyjąć, a można nie przyjmować ;) to już taka dyskusja akademicka czy zero jest liczbą naturalną, niektórzy uznają, że tak, inni że nie.

3 - możesz np. zacząć od j = 1 i przenieść j++ za ifa i będzie ok :)


Artur 03-07-2025 10:46

"przenieść j++ za ifa" - ale tutaj chyba kolejność nie ma znaczenia, bo w kodzie z odpowiedzi w pętli "do" najpierw zwiększa się zmienną "ile"; dlaczego miałoby się zaczynać od j=1?


s.gugula 03-07-2025 13:08

Ma znaczenie, bo zauważ, że gdy j wskoczy np. na wartość 11, to warunek j < limit już nie jest spełniony (czyli nie chcemy brać pod uwagę teog przypadku), a jednak w ramach ifa zostanie to zliczone jako jeden przypadek. Jeśli zatem j++ będzie po ifie, to unikniemy tego problemu. I wtedy warto zacząć od j = 1, żeby gdy na początku j jest równy 0 już tego nie zaliczyło jako przypadku (bo j%11 jest wtedy w istocie równe 0).


Artur 03-07-2025 13:48

1 - "Ma znaczenie, bo zauważ, że gdy j wskoczy np. na wartość 11, to warunek j < limit już nie jest spełniony (czyli nie chcemy brać pod uwagę teog przypadku), a jednak w ramach ifa zostanie to zliczone jako jeden przypadek." - Czemu tak miałoby się stać skoro u mnie j++ jest przed ifem?

Dlaczego w odpowiedziach w takim razie ile++ jest w ifie na początku?

// int limit = 23, liczba = 0;

        // // Używam pętli do-while, więc początkową wartość zliczeń daję równą -1,

        // // ponieważ operacja ile++ w pętli wykona się na pewno przynajmniej jeden raz,

        // // a zatem nawet jeśli nie ma ani jednej liczby spełniającej warunek,

        // // to zmienna ile będzie miała wówczas wartość 0.

        // int ile = -1; //zmienna przechowująca informację ile jest naszych liczb

        // System.out.println("Wybrany limit: " + limit);

        // do

        // {

        //     ile++;

        //     liczba += 11;

        // }

        // while (liczba < limit);

        // System.out.println("Liczb podzielnych przez 11 mniejszych od " + limit + " jest: " + ile);

      //


2 - "I wtedy warto zacząć od j = 1, żeby gdy na początku j jest równy 0 już tego nie zaliczyło jako przypadku (bo j%11 jest wtedy w istocie równe 0)." - Czyli w tym zadaniu nie zaliczamy zera do liczb naturalnych?




s.gugula 03-07-2025 15:02

1 - no właśnie dzieje się tak dlatego, że j++ jest przed ifem, więc do ifa wskakuje już jako 11, toteż jest on zliczany i dopiero potem sprawdzany jest warunek, który się nie spełnia (np. dla n = 11) i pętla się kończy. A powinno być tak, że gdy n = 11, to tego zliczenia ma tam nie być. Więc jeśli j++ będzie po ifie, to do ifa j wskoczy jako 10, więc przypadek nie zostanie zliczony, i dopiero potem wskoczy na 11 i warunek nie będzie spełniony i pętla się skończy.

W odpowiedziach jest to robione w ogóle w inny sposób, nie jedziemy ze zmienną j co jeden, tylko jak widac zmieniamy sobie naszą liczbę od razu co 11.

2 - autor najwyraźniej uznał, że nie ;)


Artur 04-07-2025 08:47

Okej, faktycznie, już rozumiem czyli ten program, który był powyżej w ifie liczył j od dwójki (bo początkowo było j=1)tak? Czyli w ten sposób jak poniżej jest poprawnie?

// b)
        int liczba = 0;
        int j = 1; // !!!tutaj 0 nie jest liczbą naturalną!!!
        do 
        {
            if(j%11==0)
            {
                liczba++; 
            }
            j++;
        }
            while(j < limit);
        System.out.println("Liczb podzielnych przez 11 mniejszych od "+limit+": "+liczba);


s.gugula 04-07-2025 10:49

Najlepiej samemu sobie sprawdzić czy jest poprawnie - przetestować ten kod dla kilku wartości i zobaczyć czy za każdym razem jest ok. Ale tak, wygląda w porządku :)


Artur 04-07-2025 12:41

// a)
        
        System.out.println("Wybrany limit: "+limit);
        int suma = 0;
        int i = 1;
        while(i < limit)
        {
            if(i%7==0)
            {
                suma += i; // suma = suma + i;
            }
            i++;
        }
        System.out.println("Suma liczb podzielnych przez 7 mniejszych od "+limit+": "+suma);


A dlaczego w tym przykładzie nie ma znaczenia czy zaczynamy od 0 czy od 1? Ten program też nie działa jak przyjmiemy i=wielokrotność 7



s.gugula 05-07-2025 12:22

Bo jeśli i będzie równe 0, to nawet jeśli je dołożymy do sumy to nic to nie zmieni ;)

A co do drugiej kwestii to ten program działa dobrze dla wielokrotności siódemki - sam to przed chwilą sprawdziłem, więc nie za bardzo wiem do czego się odnosisz?


Artur 06-07-2025 13:30

No ale jeśli i będzie równe 1 lub 7 to po dołożeniu go do sumy to już powinno się zmienić.

Co do drugiej kwestii to jednak faktycznie działa, coś mi się pomyliło.


s.gugula 06-07-2025 23:14

Ale jeśli i będzie równe 1, to if nie będzie spełniony, więc suma nie będzie zwiększana. A dla i = 7 oczywiście to już nastąpi, ale tak ma być (niezależnie czy zaczęliśmy od i = 0 czy 1).


Artur 07-07-2025 10:58

Czyli teraz rozumiem, że program działa dla dowolnego początkowego i? Dla mnie to jest dalej trochę dziwne


s.gugula 08-07-2025 23:59

Dla każdego i do siódemki. Co jest logiczne, bo do siódemki nie ma liczb podzielnych przez 7 (poza zerem, które tu pomijamy).


Artur 09-07-2025 13:39

Dziękuję :)


Zadzwoń teraz Dotknij, aby się ze mną skontaktować.