Pętle for, bez tablic

0

Witam.
Jestem pierwszy raz na forum więc może krótko o sobie. Jestem Artur i mam 15 lat, uczę się języka C++ od paru dni, wcześniej uczyłem się PHP.

Dzisiaj pierwszy raz wszedłem na stronę www.main.edu.pl i rozpocząłem rozwiązywanie zadań z kursu C++. No i, pojawiają się pierwsze problemy. Dotyczą one pewnego rodzaju zadań, np. tych:
www.main.edu.pl/pl/user.phtml?op=showtask&task=abs&con=PAS
www.main.edu.pl/pl/user.phtml?op=showtask&task=cia&con=PAS
Trzeba w nich podać różne wartości. Ilość ich niestety podawana jest w trakcie pracy uruchomionego programu więc pomysł z odgórnym zdefiniowaniem zmiennych jest zły. Poza tym mogą być ich setki tysięcy, a nikt tyle ich nie zrobi. Nie wiem jak podejść do ich rozwiązania, z wykorzystaniem tylko pętli for i kilku zmiennych.

Po co są podawane ilości liczb? Po to, żeby wykorzystać to w pętli, czy może po to, żeby stworzyć taką tablicę? Podkreślam jednak fakt, że chciałbym tutaj rozwiązanie bez tablic (następny rozdział w www.main.edu.pl wykorzystuje właśnie tablice w pętlach for, więc doszedłem do wniosku, że w tych zadaniach trzeba się bez nich obejść).

Odnośnie zadania z różnicą liczb. Jeśli już, to nawet nie wiem jak napisać skrypt wykorzystujący zmienne, ani jak napisać program, żeby porównywał każdą liczbę z każdą.

Za wszelką pomoc dziękuję

0

for to nie jedyna pętla. Spróbuj zastanowić się na while i do tego warunek. Jaki ? Ano pewno działaj tak długo jak podajemy coś na standardowe wejście. Zapewne nie są CI obce strumienie wejścia/wyjścia i ich obsługa ?

Powodzenia !

0

A po co chcesz tu coś tablicować? Czy w 2 zadaniu musisz cokolwiek mieć w jakiejs tablicy?
b1 = a1
b2 = a1+a2 = b1 + a2
b3 = a1+a3+a3 = b2+a3
...
Czyli możesz po wczytaniu kolejenego ai wypisywać na wyjściu od razu kolejne bi i jedyne co musisz pamiętać o wartość ostatniego bi

Hint dla początkującego: o ile na konsoli nie odróżniasz wejścia i wyjścia, to to są 2 różne rzeczy i spoj je rozpoznaje. Oznacza to że możesz wypisywac wyniki w trakcie czytania wejścia.

0

Nie są mi obce, korzystałem z nich na początku nauki, ale dzisiaj, na potrzeby pewnego zadania, musiałem się przerzucić na scanf() i printf().
Sugerujesz pewnie, żebym wykorzystał pętlę while z odpowiednim warunkiem (domyślam się, że wykorzystam tu pierwszą wartość, określającą ilość danych), aby wszystkie te dane zapisać. Wciąż jednak nie wiem w czym (albo jak?) je zapisać, ew. wykorzystać w biegu.

Shalom napisał(a):

(...)Czyli możesz po wczytaniu kolejenego ai wypisywać na wyjściu od razu kolejne bi i jedyne co musisz pamiętać o wartość ostatniego bi

Hint dla początkującego: o ile na konsoli nie odróżniasz wejścia i wyjścia, to to są 2 różne rzeczy i spoj je rozpoznaje. Oznacza to że możesz wypisywac wyniki w trakcie czytania wejścia.

Na stronie, którą podałem, trzeba wysyłać rozwiązania na takiej zasadzie, że:
pierwszy wers przyjmuje...
drugi wers...
a dopiero później mogą być dane z wyjścia, również podzielone na wersy. Czy w/w metodami dam radę to osiągnąć? Czy dam radę podzielić dane wejścia i wyjścia, nie mieszając ich w biegu (o ile dobrze zrozumiałem wasze sugestie na ten temat)?

1

Nie musisz ich zapisywać. Możesz po odczytaniu jednej wartości wypisać od razu wynik i wczytać kolejną wartość. System sprawdzania odczyta to poprawnie. A wczytujesz aż nie dojdzie do EOT na wejściu czyli póki się nie skończą dane.

Pani Edyta--

Wartość którą musisz przechować i dzielić we wszystkich iteracjach może być zmienną globalną.

0

czyli program będzie wiedział ile razy będę podawał dane i gdzie jest EOT?

Czym tak dokładnie jest EOT i jak działa?

0

http://en.wikipedia.org/wiki/End-of-transmission_character

Wystarczy ze będziesz sprawdzał, czy wczytany znak nie jest EOT, jeśli to EOT znaczy ze dane sie skończyły i musisz zakończyć program.

0

a jak mógłbym sprawdzić czy dany znak to EOT?

0

W warunku pętli while można wykonywać funkcje. Sprawdz co i jak zwraca strumien wejścia. Masz juz pomysł jak użyć tego jako warunku ? Jakie wartości w c++ to prawda a jakie to fałsz ?

0

Spróbuję nad tym pomyśleć, domyślam się już jak to zrobić, ale nic nie zmieniło się w stosunku do zadania z różnicami, nie wiem jak je ze sobą porównać i jak znaleźć tą największą różnicę.

0

Ale WTF? Przecież w tych zadaniach MASZ PODANE na wejściu ile ma być iteracji pęli. Gdzie tu jest problem?

int n;
scanf("%d",&n);
for (int i=0;i<n;i++){
  //CUDA! iterujemy tyle ile mamy iterować...
}
0

Fakt, zapędziliśmy się tutaj widzę w dwa różne rozumowania pytania. Jeśli chodzi o wczytywanie NIEOKREŚLONEJ liczby argumentów to użyj cin.eof() natomiast ty tutaj masz podaną ilość argumentów. Jest ich 4 i wcale nie musisz ich trwale zapisywać żeby wykonać zadanie. Potrzebujesz jednej zmiennej globalnej ponieważ żeby obliczyć B(n) musisz znać tylko B(n-1).

Jeśli już natomiast koniecznie chcesz wszystko zapisać nic nie stoi na przeszkodzie. C++ pozwala w trakcie programu deklarować kolejne zmienne czy nawet tablice dowolnej długości( o ile pamieci starczy). Służy do tego new i wskaźniki.

Podkreślam jednak jeszcze raz ze @Shalom ma racje bo nie ma potrzeby zapisywać danych wejściowych.

Pani Edyta--

4 arg. są w przykładach - liczby może być dowolna dodatnia ;p

0

Problem z zadaniem na potęgi już rozwiązałem, wystarczyło mi to:

lukas_gab napisał(a):

Nie musisz ich zapisywać. Możesz po odczytaniu jednej wartości wypisać od razu wynik i wczytać kolejną wartość. System sprawdzania odczyta to poprawnie.

Sama informacja, że dane wejściowe i wyjściowe się wtedy nie pomieszają (mogą być podzielone na wiersze) mi wystarczyła :) Wcześniej myślałem, że będzie to wyglądać tak:

WEJŚCIE
WYJŚCIE
WEJŚCIE
WYJŚCIE
...

Spieszyłem się i trochę namieszałem. Teraz problem tkwi tylko w zadaniu z różnicami. Tam każda liczba musi być porównana z każdą. Nie potrafię wykorzystać tych informacji w tym zadaniu.

Mam tylko jedno pytanie. Czemu gdy zdefiniowałem zmienną b wewnątrz funkcji main() wyskoczyły mi na wyjściu śmieci? Gdy przypisałem do niej wartość 0 (która, jak dobrze wiem, jest automatycznie przypisywana pustym zmiennym) wszystko działało poprawnie. Z kolei gdy zdefiniowałem ją globalnie, poza funkcją main(), wszystko było OK i nie musiałem przypisywać wartości 0.

#include <cstdio>

int main()
{
	int n, a, b = 0;
	scanf("%d", &n);
	for(int i = 1; i <= n; i++)
	{
		scanf("%d", &a);
		b += a;
		printf("%d ", b);
	}
}
1

Ponieważ w C/C++ zmiennym alokowanym na stosie nie jest przypisywana żadna wartość. Zawierają śmieci, które w tym miejscu były wcześniej. Zmienne globalne są inne, są one zadeklarowane w segmencie .data kodu i one są automatycznie ustawiane na domyślną wartość (czyli 0) lub na ustaloną przez kod. Co innego zmienne zadeklarowane na stercie (czyli przy użyciu new). One są automatycznie zerowane (nie działa to przy użyciu malloc).

1
AKZ napisał(a):

Mam tylko jedno pytanie. Czemu gdy zdefiniowałem zmienną b wewnątrz funkcji main() wyskoczyły mi na wyjściu śmieci? Gdy przypisałem do niej wartość 0 (która, jak dobrze wiem, jest automatycznie przypisywana pustym zmiennym) wszystko działało poprawnie. Z kolei gdy zdefiniowałem ją globalnie, poza funkcją main(), wszystko było OK i nie musiałem przypisywać wartości 0.

Dlatego, że zmienna trzeba inicjalizować. Kiedy nie zainicjalizujesz zmiennej to zostaną jej przypisane śmieci. Zmienne lokalne należy "ręcznie" zerować. Zmienne globalne są zerowane z automatu.
Co do problemu - to, żeby porównywać każdą liczbę z każdą, musisz skorzystać z dwóch pętli for (jedną zagnieździć w drugiej). Wtedy możesz porównywać każde liczby ze sobą i ustalać maksymalną różnicę między nimi.

0

Napisałem taki oto program. Dotyczy on "największej różnicy". Kilka wyjaśnień.

  1. Wyrzuciłem przed pętlę dwie pierwsze zmienne dlatego, że w przypadku gdy zmienne pierwotnie mają wartość 0 (w przypadku zmiennych globalnych) lub śmieci (w przypadku stosu), ich porównanie może być błędne, a w wyniku złe przypisanie wartości min i max. Jak pozbyć się tego problemu i wrzucić wszystko do pętli?
  2. Dodałem w pętli dwie instrukcje if, które porównują liczby. Dodałem else, żeby w przypadku prawdziwości pierwszego warunku, nie był sprawdzany drugi warunek (bez else byłyby sprawdzane oba).
  3. Założyłem, że wszystkie zmienne są int, a nie float (jak w zadaniu).
    Jaki jest lepszy sposób, bo wiem, że taki istnieje? Pomysłu z dwiema pętlami nie wykorzystam ;) ale nie wiem czy mój program ma złożoność liniową...
#include <cstdio>
int n, min, max, pom;

int main()
{
	scanf("%d", &n);
	scanf("%d", &max);
	scanf("%d", &min);
	if(min > max)
	{
		pom = max;
		max = min;
		min = pom;
	}
	for(int i = 3; i <= n; i++)
	{
		scanf("%d", &pom);
		if(pom > max)
			max = pom;
		else if(pom < min)
			min = pom;
	}
	printf("%d", max - min);
}

I jak zmniejszyć wcięcia w kodzie? Zwykły tabulator daje za duże wcięcie.

1 użytkowników online, w tym zalogowanych: 0, gości: 1