Odwoływanie się do indeksów, liczenie odległości między nimi i losowe liczby w C++

2

OK. Już to słyszałem. To nie jest „bardzo dokładna” informacja o tym co robisz, to jest tylko informacja o tym, co chcesz, żeby było zrobione. To nie jest to samo…

Używając metafory, to tak, jakbyś odpowiadał „jadę do Krakowa, na Tkacką 17/2B”, zapytany o to, jaką trasą jedziesz. A tutaj trzeba krok po kroku: „wyjeżdżam na obwodnicę, kieruję się na A4, jadę pod sam Kraków, zjeżdżam przy…”

To nie jest trywialne zadanie. Ono ma pewien niezerowy poziom algorytmiczny — czyli w zrozumieniu, jak to zrobić, krok po kroku. Nie ma znaczenia, czy na kartce papieru, czy na komputerze. Jest to coś, co trzeba samemu zrozumieć. I nie wiem, czy Ty to rozumiesz czy nie, a jeśli tak, to w jakim stopniu…

I jest też znajomość języka, którym się operuje przy tłumaczeniu komputerowi, jak i co ma zrobić. Tutaj jasnym jest, że C++ stwarza Ci ogromne problemy. Zatem doradzę Ci, jeszcze raz, tak: zostaw to zadanie. Naucz się podstaw C++ — w szczególności tego, jak działają pętle. Potem możesz wrócić do tego zadania — i wymyślić, jak krok po kroku je zrobić. I wreszcie poskładać te dwie rzeczy ze sobą — czyli wyjaśnić komputerowi, przy użyciu C++, jak on ma je rozwiązać.

Pobierze od użytkownika ile liczb ma być w tablicy, a potem jakie te liczby są, dlatego zmienna n i a.
n przechowuje ilość liczb, natomiast a ich wartość, 1 lub 0.

Nie wiesz zatem, co to jest zmienna typu int, której używasz. int przechowuje jedną wartość. Jak się chce mieć więcej, to potrzeba mieć kolekcję tych intów — na przykład tablicę czy (tutaj znacznie lepiej) wektor.

Spróbuj, samemu czy tutaj na forum, opisać swoimi słowami, krok po kroku, co każda linijka robi. Nie co Ty chcesz, żeby robiła, tylko co faktycznie dla komputera oznaczają te zapiski. Przykład:

int n,a,k;  // deklaruję trzy zmienne globalne, n, a oraz k; są one domyślnie ustawiane na 0
int main()
{
    cin >> n;  // przyjmuję od użytkownika liczbę całkowitą i wrzucam ją do n
    cin >> a;  // przyjmuję od użytkownika liczbę całkowitą i wrzucam ją do a
    for(int t[n];a<n-1;a++)  // zaczynam od deklaracji VLA tablicy intów o rozmiarze n; a potem w pętli, tak długo jak a jest mniejsze od n-1, wykonuję poniższe instrukcje, a na koniec zwiększam a o jeden
        if(a==1)  // i tak dalej
            cout<< k+1;
        else
            cout<< " ";

    return 0;
}

Pomoże Ci to, być może, zobaczyć, co tak dokładnie robisz, i że nie ma to absolutnie nic wspólnego z Twoim zamierzonym celem.

0

Zaznaczam, aktywnie modyfikuje kod, zgodnie z Twoimi radami.

}
int n,a,k;///przeniosłem zmienne do main.
    cin >> n;///pobiera liczby od użytkownika i zapamiętuje pod n
    cin >> a;///pobiera liczby od użytkownika i zapamiętuje pod a
    for(std::vector<int> t(a);a<n;n--)///(Co mi sie wydaje że komputer pomyśli) Mam wektor t o długości a, czyli tyle ile ta zmienna z wcześniej. I mam tą pętle robić dopóki dopóty N nie będzie większe od A. Za każdym razem zmniejszam watrość n o 1.
        if(a==1)/// jeśli pierwsza pozycja w wektorze ma wartość 1
            cout<< k+1;///to zwiększam k o 1
        else///jeśli jest coś innego to rozpoczynam pętle od nowa.
            continue;

    return 0;
}
2

OK, już zaczynam rozumieć, co próbujesz zrobić — więc i czemu Ci nie wychodzi.

Zatem:

  1. std::vector<int> t(a) to „pusty” wektor — w nim będzie a domyślnie zainicjalizowanych zmiennych typu int, czyli zer.
  2. a to nie jest „pozycja w wektorze”, tylko a — jakaś liczba, konkretnie długość tego wektora. Zerowa (w C++ elementy kolekcji o długości n są numerowane od zera do n-1) pozycja w wektorze t to t[0], piąta to t[5], a m-ta¹ to t[m].
  3. cout << k + 1 nie zwiększa k o jeden, tylko wypisuje na ekran wartość k+1. Czyli — nie wiadomo co. Bo co jest, Twoim zdaniem, w k i skąd komputer miałby o tym wiedzieć? Jak chcesz mu powiedzieć, że chcesz, żeby k było intem o wartości 0, to mu to powiedz: int k = 0;.
  4. Nie ma sensu mieć continue, które nie przeskakuje nad żadnymi instrukcjami.
  5. Za to jest wielki sens ujęcia ciała pętli w klamrę, nawet jeśli teraz nie jest to ściśle niezbędne — bo za chwilę może się okazać, że będzie, a Ty to przeoczysz.

¹ Dobór litery przypadkowy, nie sugeruj się tym, to tylko znaczki.

0
  1. a to nie jest „pozycja w wektorze”, tylko a — jakaś liczba, konkretnie długość tego wektora. Zerowa (w C++ elementy kolekcji o długości n są numerowane od zera do n-1) pozycja w wektorze t to t[0], piąta to t[5], a m-ta¹ to t[m].

To jak mam się odwołać do konkretnego miejsca w tym wektorze.

  1. cout << k + 1 nie zwiększa k o jeden, tylko wypisuje na ekran wartość k+1. Czyli — nie wiadomo co. Bo co jest, Twoim zdaniem, w k i skąd komputer miałby o tym wiedzieć? Jak chcesz mu powiedzieć, że chcesz, żeby k było intem o wartości 0, to mu to powiedz: int k = 0;.

K jak sam mówiłeś parę postów wcześniej, jest intem, czyli jest startowo przypisana do zera, stąd brak pisania czym to k jest. I w takim razie, jak miałbym w nowej linijce zwiększyć k?

  1. Nie ma sensu mieć continue, które nie przeskakuje nad żadnymi instrukcjami.

Zapamiętam

  1. Za to jest wielki sens ujęcia ciała pętli w klamrę, nawet jeśli teraz nie jest to ściśle niezbędne — bo za chwilę może się okazać, że będzie, a Ty to przeoczysz.

Dziękuje? już nie wiem czy to sarkazm czy tak myślisz

0

To jak mam się odwołać do konkretnego miejsca w tym wektorze.

Tak jak Ci pisałem. „zerowa (w C++ elementy kolekcji o długości n są numerowane od zera do n-1) pozycja w wektorze t to t[0], piąta to t[5], a m-ta to t[m]”.

K jak sam mówiłeś parę postów wcześniej, jest intem, czyli jest startowo przypisana do zera, stąd brak pisania czym to k jest. I w takim razie, jak miałbym w nowej linijce zwiększyć k?

To jest… trochę bardziej finezyjne. Domyślna inicjalizacja inta faktycznie ustawia go na zero, ale Ty go w ogóle nie inicjalizujesz — mógłbyś to zrobić zadaną wartością, czyli na przykład int k = 0; (czy 4, czy 17, czy cokolwiek), albo domyślnie int k {}; A żeby było jeszcze gorzej, to zmienne globalne domyślnie inicjalizowane… a lokalne nie. Jest to ogólnie dosyć paskudny element C++, jak będziesz chciał sobie o tym kiedyś poczytać (raczej nie teraz), to https://en.cppreference.com/w/cpp/language/default_initialization A na razie, załóż po prostu, że jak komputerowi nie powiesz wprost, jaka ma być wartość, to nie będzie wiedział. Tak jest znacznie bezpieczniej.

Dziękuje? już nie wiem czy to sarkazm czy tak myślisz

To była poważna porada. Powinieneś to zrobić. Na razie tego nie zrobiłeś. Nie używam sarkazmu jak komuś coś tłumaczę, szczególnie że mój suchy, autyczny¹ humor nie do wszystkich trafia.

¹ czy też „autystyczny”, jak chcą niektóre słowniki; w każdym razie — od autyzmu

0

Na razie ze wszystkich rad, tak wygląda pętla.

for(std::vector<int> t(a); a < n; n--) 
        {
            if(t(a)==1)
                k+1;
                cout<< k;
       }
3

Wiesz co, wybacz, ale to zaczyna być dla mnie niestety za bardzo pracochłonne. Musisz dobrze zrozumieć podstawy C++, żeby temu podołać.

Możesz się nauczyć z książek: na pewno „C++ Programming Language” od Stroustrupa jest dobre (i wydane po polsku, jak Ci na tym zależy). Być może inne książki też są dobre.

Możesz się nauczyć z Internetu: na pewno Zelent jest zły. Być może inni są dobrzy.

Mogę też wreszcie nad tym posiedzieć z Tobą, ale ze względu na ilość czasu, jaki trzeba na to poświęcić — już nie za darmo. Pójdziemy po bandzie, cena-minimum (normalnie zarabiam więcej…) — 50 zł za godzinę, co najmniej dwie godziny, płatne z góry.

Sugerowałbym raczej którąś z tych dwóch pierwszych metod (bo Ci wyjdą taniej), ale ja nie będę niestety skłonny do spędzania nad tym większej ilości czasu za darmo. Mam swoje życie, swoje koty, swoją rodzinę i przyjaciół, czy wreszcie nawet swoje książki i gry komputerowe… Nie chcę Cię naciągać — tak jak mówię, lepiej Ci wyjdzie któraś z tamtych metod — ale też i nie chcę samemu dawać się naciągać.

0

Nie chcę tam cytować jakichś postów, nie zamierzam zelenta bronić, ale pierwszy raz widzę, żeby ktoś z prawie zerowym zrozumieniem pętli rzucił "Oglądałem poradniki, ale okazały się (ekhem) jak to jeden z użytkowników podsumował autora tych poradników "Zelent to przekleństwo internetu"". Szczególnie, jeżeli w ostatnim czasie piszesz kolejny temat z tym samym problemem. Jasne, że należy wytkać błędy, tym bardziej jeżeli są one w tutorialach dla początkujących, ale śmiesznie jest to robić, jeśli się tych błędów w ogóle nie widzi. Tobie sporo by pomogły nawet takie tutoriale.

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