• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Wypisz liczby w kolejności malejącej nie używając tablic

Aruba Cloud PRO i VPS, Openstack, VMWare, MS Hyper-V
0 głosów
1,412 wizyt
pytanie zadane 13 października 2018 w C i C++ przez Vitall Początkujący (400 p.)

Cześć,

mam zadanie następującej treści:

"Napisz program pobierający od użytkownika dwie liczby całkowite stanowiące krańce pewnego przedziału domkniętego, a następnie wypisujący ilość i sumę liczb podzielnych przez 3 należących do tego przedziału, a także wszystkie te liczby w kolejności malejącej."*

Chodzi o to by nie używać tablic ani innych struktur danych, które mogłyby je przechowywać.**

Wszystko super spoko, tylko to wypisanie liczb w kolejności malejącej..

Mój kod:


#include<iostream>	
#include<limits>

using namespace std;

int main()
{
	int a , b, liczba_prob = 0, ile_liczb = 0, suma = 0, max = numeric_limits<int>::min();
	bool czy_byly_liczby;

	do 
	{
		cout << "Podaj krance przedzialu domknietego. \nLewy - a, prawy - b.\na = ";
		cin >> a;
		cout << "b = ";
		cin >> b;
		if (a>b)
		{
			cout << "a  > b, wiec przedzial nie istnieje!" << endl;
			liczba_prob++;
			cout << "Pozostalo Ci: "<< 5-liczba_prob << " prob(a/y)."<< endl;
		}
		else if (a == b)
		{	
			cout << "a == b, wiec przedzial jest zdegenerowany!" << endl;
			liczba_prob ++;
			cout << "Pozostalo Ci: "<< 5-liczba_prob << "prob."<< endl;
		}
		else
			break;
		
	}
	while(liczba_prob != 5);
	
	if (liczba_prob >= 5)
		cout << "Liczba dopuszczalnych prob wynosila 5! Nie masz wiecej prob!!";
	
	for (int i = a; i <= b ; i++)
	{
		if (i % 3 == 0)
			{
				ile_liczb ++;
				suma = suma + i;
				czy_byly_liczby = true;
				if (i > max)	
					max = i;
			}
		else
			czy_byly_liczby = false;

	}
	
	if (czy_byly_liczby == true)
		cout << "nawjwieksza z liczb podzielnych przez 3 w tym przedziale, to: "
			 << max << endl;


		
			
	
	
	
	
	cout << "W przedziale a = " << a << ", b = " << b <<" jest " << ile_liczb 
	<< " liczb podzielnych przez 3. Ich suma wynosi: " << suma << "." << endl;
	
	
	

	
	
	
	return 0;
}

Proszę o podpowiedź/naprowadzenie.

Brakuje mi czegoś, co by "zapamiętywało" te wybrane liczby (podzielne przez 3), a nie mogę mieć zmiennej na każdą taką liczbę, bo raz nie wiem z góry ile takich liczb będzie, dwa, nawet jakbym wiedział, to bez sensu tworzyć miliony zmiennych na to samo.

 

* Ja sobie zmodyfikowałem treść, żeby użytkownik mógł max 5 razy wpisać [a;b] aż przedział będzie sensowy.

** Zadanie ma nacisk na to, że ma być bez tablic - to nie są moje "widzimisię" ;)

komentarz 14 października 2018 przez mokrowski Mędrzec (151,300 p.)
Nie lepiej pójść nieco inną drogą?

1. Wczytać krańce przedziału.

2. Wykryć czy nie zachodzi przypadek: a > b oraz a == b

3. Obliczyć: z a pierwszy indeks, z b drugi indeks ("wyrównane do liczby podzielnej przez 3")

4. Sprawdzić czy nie zachodzi przypadek: indeks_a >= indeks_b i jeśli zachodzi zgłosić brak liczb.

5. Wykonać obliczenia

???

1 odpowiedź

+1 głos
odpowiedź 13 października 2018 przez niezalogowany
wybrane 13 października 2018 przez Vitall
 
Najlepsza

Od razu wyszukaj najmniejszą i największą liczbę podzielną przez 3. Następnie iteruj pętlę po tych wartościach o 3 jednostki (unikniesz iterowania co jeden). Możesz też zostawić wszystko jak jest, a przy wypisywaniu od tych liczb użyć podobnej pętli tylko iterowanej w innym kierunku:

for (int i = b; i >= a ; --i)

PS. W obecnym kodzie masz duże uchybienie:

else
            czy_byly_liczby = false;

w przypadku gdy po podzielnej przez 3 liczbie będzie niepodzielna fladze zostanie przypisana zła wartość. Najlepiej usunąć te dwie linie i od razu zainicjować flagę na false.

PPS. Gdy użytkownik wykorzysta swoje próby możesz zakończyć program:

if (liczba_prob >= 5)
{
        cout << "Liczba dopuszczalnych prob wynosila 5! Nie masz wiecej prob!!";
        return 0;
}
komentarz 13 października 2018 przez Vitall Początkujący (400 p.)
edycja 13 października 2018 przez Vitall

@Hipcio - dzięki wielkie za podpowiedzi. 

Zastosowałem się do wszystkich poza pierwszą, której nie umiem zrobić. 
Chociaż to z ustawieniem zmiennej czy_byly_liczby na false, po usunięciu błędnej instrukcji (dzięki za wytknięcie) nie jest dla mnie do końca jasne, tzn. nie wiem co dokładnie masz na myśli. Wg mnie po usunięciu błędu, nie trzeba już nic dopisywać, bo program działa poprawnie (przynajmniej kilka razy testując nie wyskoczył mi żadnen błąd).

Prosiłbym o "rzucenie okiem", czy teraz program nie ma błędów. 

Od razu wyszukaj najmniejszą i największą liczbę podzielną przez 3. Następnie iteruj pętlę po tych wartościach o 3 jednostki (unikniesz iterowania co jeden)

Tego nie umiem, nie wiem jak to zrobić.
 

Mój kod, po poprawkach:

#include<iostream>	
#include<limits>

using namespace std;

int main()
{
	int a, b, liczba_prob = 0, ile_liczb = 0, suma = 0, max = numeric_limits<int>::min();
	bool czy_byly_liczby;

	do 
	{
		cout << "Podaj krance przedzialu domknietego. \nLewy - a, prawy - b.\na = ";
		cin >> a;
		cout << "b = ";
		cin >> b;
		if (a>b)
		{
			cout << "a  > b, wiec przedzial nie istnieje!" << endl;
			liczba_prob++;
			cout << "Pozostalo Ci: "<< 5-liczba_prob << " prob(a/y)."<< endl;
		}
		else if (a == b)
		{	
			cout << "a == b, wiec przedzial jest zdegenerowany!" << endl;
			liczba_prob ++;
			cout << "Pozostalo Ci: "<< 5-liczba_prob << "prob."<< endl;
		}
		else
			break;
		
	}
	while(liczba_prob != 5);
	
	if (liczba_prob >= 5)
	{
		cout << "Liczba dopuszczalnych prob wynosila 5! Nie masz wiecej prob!!";
		return 0; // jak użtykownik nie wykorzysta prób, to kończymy program
	}
		
	for (int i = a; i <= b ; i++)
	{
		if (i % 3 == 0)
			{
				ile_liczb ++;
				suma = suma + i;
				czy_byly_liczby = true;
				if (i > max)	
					max = i;
			}
					
	}
	
	if (czy_byly_liczby == true)
	{
		cout << "W przedziale [" << a << "," << b <<"] jest " << ile_liczb 
			 << " liczb podzielnych przez 3."
			 << endl <<  "Ich suma wynosi: " << suma << "." << endl;
			 
		cout << "Najwieksza z tych liczb:  "
			 << max << endl << "Liczby podzielne przez 3 z tego przedzialu w kolejnosci malejacej: "
			 << endl;
			 
		for (int i = b; i >= a; i--)
		{
			if (i % 3 == 0)
				cout << i << endl;
		}
			
	}
	else 
	cout << "W przedziale nie bylo liczb podzielnych przez 3.";
	
	return 0;
}

 

1
komentarz 13 października 2018 przez niezalogowany

W pierwszym kodzie dla danych wejściowych {2, 5} zmienna czy_byly_liczby ma wartość false - mimo, że 3 spełnia kryteria. Po prostu kolejne liczby 4 i 5 nie spełniają warunku i w else wartość true została zastąpiona false. To prowadziło do niewyświetlania max.

Teraz kod wygląda prawie dobrze. Brakuje jeszcze inicjowania zmiennej czy_byly_liczby na false. Inaczej może zostać zostać jej nadana przypadkowa wartość. Reszta tak na oko jest poprawna.

Ten pierwszy sposób o którym wspomniałem wymaga troszkę więcej linii kodu, ale za to będzie mniej porównań (tak ze 7 razy mniej). Z grubsza początek polegałby na znalezieniu dwoma pętla min i max, a reszta na nich operowaniu:

    if (czy_byly_liczby == true)
	{
		for (int i = min; i <= max; i += 3)
		{
			ile_liczb++;
			suma += i;
		}

		cout << "W przedziale [" << a << "," << b << "] jest " << ile_liczb
			<< " liczb podzielnych przez 3."
			<< endl << "Ich suma wynosi: " << suma << "." << endl;

		cout << "Najwieksza z tych liczb:  "
			<< max << endl << "Liczby podzielne przez 3 z tego przedzialu w kolejnosci malejacej: "
			<< endl;

		for (int i = max; i >= min; i -= 3)
		{
			cout << i << endl;
		}
	}

komentarz 13 października 2018 przez Vitall Początkujący (400 p.)

  @Hipcio,


Teraz kod wygląda prawie dobrze. Brakuje jeszcze inicjowania zmiennej czy_byly_liczby na false. Inaczej może zostać zostać jej nadana przypadkowa wartość. Reszta tak na oko jest poprawna.

Może ja naprawdę póki co jeszcze nie chwytam, ale u mnie jest tak:
 

		
	for (int i = a; i <= b ; i++)
	{
		if (i % 3 == 0)
			{
				ile_liczb ++;
				suma = suma + i;
				czy_byly_liczby = true;
				if (i > max)	
					max = i;
			}
					
	}
	

więc wg mnie, jeżeli będę miał przedział, np [1,2], to warunek w if-ie zawsze będzie "false", więc if się nie wykona, flaga będzie... a! przy definiowaniu zmiennej trzeba określić, że czy_byly_liczby = false? Zainicjować wartość, o to Ci chodzi?** ;) Chociaż ile razy wpisywałem, np. [1,2], czy [4,5] i tego typu, to zawsze działał poprawnie - czyżby poprawność losowa?

Dzięki za tę podpowiedź do drugiego rozwiązania  - muszę to jeszcze przetrawić.

** ok, przecież to napisałeś - późno jest, przepraszam

Wersja ostateczna (na dziś):
 


using namespace std;

int main()
{
	int a, b, liczba_prob = 0, ile_liczb = 0, suma = 0, max = numeric_limits<int>::min();
	bool czy_byly_liczb = false;

	do 
	{
		cout << "Podaj krance przedzialu domknietego. \nLewy - a, prawy - b.\na = ";
		cin >> a;
		cout << "b = ";
		cin >> b;
		if (a>b)
		{
			cout << "a  > b, wiec przedzial nie istnieje!" << endl;
			liczba_prob++;
			cout << "Pozostalo Ci: "<< 5-liczba_prob << " prob(a/y)."<< endl;
		}
		else if (a == b)
		{	
			cout << "a == b, wiec przedzial jest zdegenerowany!" << endl;
			liczba_prob ++;
			cout << "Pozostalo Ci: "<< 5-liczba_prob << "prob."<< endl;
		}
		else
			break;
		
	}
	while(liczba_prob != 5);
	
	if (liczba_prob >= 5)
	{
		cout << "Liczba dopuszczalnych prob wynosila 5! Nie masz wiecej prob!!";
		return 0; // jak użytkownik nie wykorzysta prób, to kończymy program
	}
		
	for (int i = a; i <= b ; i++)
	{
		if (i % 3 == 0)
			{
				ile_liczb ++;
				suma = suma + i;
				czy_byly_liczby = true;
				if (i > max)	
					max = i;
			}
					
	}
	
	if (czy_byly_liczby == true)
	{
		cout << "W przedziale [" << a << "," << b <<"] jest " << ile_liczb 
			 << " liczb podzielnych przez 3."
			 << endl <<  "Ich suma wynosi: " << suma << "." << endl;
			 
		cout << "Najwieksza z tych liczb:  "
			 << max << endl << "Liczby podzielne przez 3 z tego przedzialu w kolejnosci malejacej: "
			 << endl;
			 
		for (int i = b; i >= a; i--)
		{
			if (i % 3 == 0)
				cout << i << endl;
		}
			
	}
	else 
	cout << "W przedziale nie bylo liczb podzielnych przez 3.";
	
	return 0;
}

 

komentarz 13 października 2018 przez niezalogowany
@Vitall wszystko przyjdzie z czasem ;) Jeżeli zmienna nie będzie zainicjowana to będzie miała taką wartość jak komórka pamięci przed działaniem programu. Więc mogą (ale nie muszą) pojawić się jakieś śmieci. Czasami uruchamiając 100 razy ten sam program nie zauważysz tego, bo akurat zawsze zostanie przydzielona ta sama komórka. Może też okazać się, że kompilator zawsze inicjuje zmienne wartością domyślną, ale to nie jest reguła. Standard C++ wymaga takiego zachowania tylko dla zmiennych statycznych czy globalnych.

Podobne pytania

0 głosów
1 odpowiedź 1,264 wizyt
pytanie zadane 7 listopada 2017 w C i C++ przez rayman22 Użytkownik (710 p.)
0 głosów
1 odpowiedź 94 wizyt
pytanie zadane 19 stycznia 2016 w C i C++ przez TheFunny Gaduła (3,420 p.)
0 głosów
2 odpowiedzi 231 wizyt
pytanie zadane 7 stycznia 2017 w C i C++ przez pokrywa1 Użytkownik (990 p.)

89,728 zapytań

138,332 odpowiedzi

309,340 komentarzy

59,649 pasjonatów

Advent of Code 2022

Top 15 użytkowników

  1. 429p. - Argeento
  2. 427p. - nidomika
  3. 396p. - Mikbac
  4. 392p. - ssynowiec
  5. 390p. - Łukasz Eckert
  6. 387p. - TheLukaszNs
  7. 386p. - rucin93
  8. 382p. - Michal Drewniak
  9. 382p. - Marcin Harasimowicz
  10. 378p. - JMazurkiewicz
  11. 373p. - tokox
  12. 362p. - adrian17
  13. 359p. - overcq
  14. 350p. - Mawrok
  15. 345p. - Vinox
Szczegóły i pełne wyniki

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Sklep oferujący ćwiczenia JavaScript, PHP, rozmowy rekrutacyjne dla programistów i inne materiały

Oto dwie polecane książki warte uwagi. Pełną listę znajdziesz tutaj.

...