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.
"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?
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).
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?
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 ;)
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);
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 :)
// 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
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?
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.
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).
Czyli teraz rozumiem, że program działa dla dowolnego początkowego i? Dla mnie to jest dalej trochę dziwne
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).
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 :)