25.* Napisz program, w którym początkowo zdefiniowana jest jedna zmienna typu całkowitego,
będąca liczbą dodatnią. Program ma wyświetlić na ekranie liczby od 1 do danej liczby w postaci
trójkąta, tak, by każdy kolejny wiersz zawierał o jeden element więcej niż poprzedni, patrz poniżej.
Przykładowy wynik działania programu:
Wybrany limit: 10
1
2 3
4 5 6
7 8 9 10
Jeśli wybrana liczba ma wartość, która sprawia, że trójkąt się nie „zakończy”, to program ma uciąć
ostatni wiersz i wyświetlić na ekranie informację o tym ile elementów zostało uciętych. Przykładowo:
Wybrany limit: 31
1
2 3
4 5 6
7 8 9 10
11 12 13 14 15
16 17 18 19 20 21
22 23 24 25 26 27 28
Trójkąt został ucięty. Ucięte elementy: 3
Czy mógłby Pan wytłumaczyć kod z odpowiedzi? Kompletnie nie wiem jak zacząć to zadanie (udało mi się tylko wypisać po jednej liczbie w każdym wierszu) i nawet kodu z odpowiedzi nie mogę zrozumieć :/
int limit = 31; // limit całego trójkąta
int rzad = 1; // aktualny rząd w którym się znajdujemy
int liczba = 1; // aktualna liczba do wyświetlenia
boolean uciety = false; // zmienna mówiąca nam o tym czy trójkąt został ucięty
System.out.println("Wybrany limit: "+limit);
while(liczba <= limit) // sprawdzam czy cały ten rzad się zapełni - jeśli tak to robię to, jeśli nie to idę do else - zaznaczam, że trójkąt został ucięty i wychodzę z pętli
{
if((liczba - 1 + rzad) <= limit)
{
for (int i = 1; i <= rzad ; i++)
{
// wypisuję liczbę i zwiększam jej wartość
System.out.print(liczba + " ");
liczba++;
}
// przejście do kolejnego rzędu
System.out.println("");
rzad++;
}
else
{
uciety = true;
break; // wyjście z pętli while
}
}
if (uciety)
{
System.out.println("Trojkat zostal uciety. Uciete elementy: " + (limit - liczba + 1));
}
1 - Czy ja dobrze wnioskuję, że zmienna liczba to jedynie pierwsza liczba w każdym rzędzie? Nie wiem dlaczego, ale tak to według mnie wygląda
2 - "A ten if, który wygląda dość skomplikowanie jest tam po to, żeby sprawdzić czy ma nastąpić to "ucięcie" ostatniego rzędu" - chodzi o tego ostatniego ifa?
if (uciety)
{
System.out.println("Trojkat zostal uciety. Uciete elementy: " + (limit - liczba + 1));
}
Jeśli tak czy if (uciety) znaczy tyle co if(uciety = true)? Przecież uciety musi mieć wartość true lub false, bo to boolean.
Nie no liczba to jest każda kolejna liczba - przeciez na ekran właśnie wartość zmiennej liczba jest wypisywana, więc ona każdorazowo z kolejną liczbą z trójkąta się zmienia.
Drugie pytanie: if (uciety) to to samo co if (uciety == true) ---> nie if (uciety = true), bo przypominam, że pojedyncze = to operator przypisania. No i nie ma tu żadnej sprzecznosci, uciety jest zmienna typu boolean. A w nawiasie w warunku ifa ma być właśnie wyrażenie typu boolean, wiec mozna tam wpisac samo uciety (bedzie to albo true albo false) i bedzie ok. Można też wpisac uciety == true i efekt bedzie identyczny, bedzie to po prostu sprawdzalo czy uciety ma wartosc true czy nie.
1 - Czy dobrze rozumiem, że limit - liczba + 1 to dla limit=31, liczba będzie równa 29 (pierwsza niewypisana) i wtedy 31-29+1=3?
2 - Jak rozumieć wtedy liczba - 1 + rzad <= limit? Według mnie wychodzi na to, że liczba = 24 powinna być ostatnią wypisaną, bo wtedy zgodnie z tym wzorem: 24-1+8=31=limit
1 - tak
2 - nie, bo ten if nie jest sprawdzany dla każdej kolejnej liczby, zauważ, że w jego wnętrzu siedzi cała pętla for odpowiedzialna za wypisanie całego rzędu na ekran. Więc tu sprawdziło, że dla 22 to jest ok, a kolejne sprawdzenie będzie dopiero dla 29.
No nie sprawdzi tego, bo specjalnie został tak skonstruowany ten warunek: (liczba - 1 + rzad). I ja wiem, że dla 25 to już nie jest prawda, ale w naszym przypadku 25 należy jeszcze do pełnego rzędu wieć ma się wypisać normalnie i tak zapisany powyższy warunek sprawia, że tak się właśnie stanie. Ale jeśli ustawisz np. limit = 25 to oczywiście 22, 23, 24 i 25 nie zostaną wypisane, więc tu wszystko jest ok.
To ja teraz rozumiem w ten sposób, że jeśli pierwsza liczba z rzędu spełnia ten warunek to znaczy, że można wypisać cały rząd tak? Bo jest to niezbyt intuicyjne według mnie
Ale ten if nie sprawdza tego czy pierwsza liczba z całego rzędu jest mniejsza niż limit, tylko sprawdza czy takie wyrażenie (liczba - 1 + rzad) jest mniejsze niż limit. I tak zapisany warunek jednoznacznie określa czy da się wypisać cały rząd czy też nie.
Ciężko wytłumaczyć linijkę po linijce, ale w ogólności chodzi o to, że mamy dwie pętle. Pętla zewnętrzna while sprawdza po prostu kiedy trzeba już w ogóle zakończyć cały proces (stąd warunek liczba <= limit). Wewnątrz mamy druga pętlę, służącą do wypełniania liczbami kolejnych rzędów, gdzie wykorzystywany jest fakt, że jeśli mamy np. rząd nr 4, to zawiera on 4 liczby, jeśli mamy rząd nr 7, to jest w nim 7 liczb itd. Stąd int i = 1, a warunek zakończenia pętli jest taki, że i <= rzad - czyli zmienna i jest zmienną iteracyjną dla każdego kolejnego rzędu z osobna. A ten if, który wygląda dość skomplikowanie jest tam po to, żeby sprawdzić czy ma nastąpić to "ucięcie" ostatniego rzędu. Prostsza wersja programu byłaby wersją bez tego warunku i wtedy nie mielibyśmy tego obcinania.