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

0

Dzień dobry,
Mam pytanie, mam tablice** t [ i ]** gdzie i wpisuje użytkownik programu.

Po pierwsze, jak mogę się odnosić do poszczególnych indeksów w tej tablicy.

Po drugie, indeksy te, mają być wcześniej wylosowane, w zakresie od 0...1.

Po trzecie, Powiedzmy że mamy taką sytuację cpp 0 1 1 0 0. Ponieważ tak wylosowała liczba. Jak mam w takim przypadku obliczyć liczbę indeksów do najbliższego 0, począwszy od pierwszej liczby z lewej, czyli 0.

Jak wyglądałby kod robiący te trzy rzeczy.

4

Przepisz może swoje pytania tak, żeby były bardziej czytelne…

Po pierwsze, jak mogę się odnosić do poszczególnych indeksów w tej tablicy.

Przez i. i jest Twoim indeksem…

Po drugie, indeksy te, mają być wcześniej wylosowane, w zakresie od 0...1.

To nie jest pytanie. Ale indeksy w C++ są liczbami naturalnymi, czyli w tym zakresie są tylko dwa — zero i jedynka. Na pewno o to Ci chodziło?

Powiedzmy że mamy taką sytuację cpp 0 1 1 0 0.

Co? Jaka to sytuacja? W ogóle nie rozumiem tego zdania…

Ponieważ tak wylosowała liczba.

Co zrobiła liczba?

Jak mam w takim przypadku obliczyć liczbę indeksów do najbliższego 0, począwszy od pierwszej liczby z lewej, czyli 0.

Liczbę indeksów? Jeśli byś miał te sześć powyższych stringów w tablicy, pierwsze zero ma indeks 1, czy o to Ci chodziło?

0

Pytanie od tego zadania
a same pytania z poprzedniego postu, były o mojej koncepcji na rozwiązanie tego zadania, ale nie wiem jeszcze nic o C++ więc musiałem sie pytać tutaj.

W pewnym sadzie rosną grusze i jabłonie, wszystkie w linii prostej, oddalone co 1 metr od siebie. Właściciel sadu, Pan Wiktor, chciałby znaleźć gruszę najbardziej oddaloną od jabłoni. Pomóż mu znaleźć te drzewa i podaj odległość pomiędzy nimi.

Wejście
Pierwszy wiersz wejścia zawiera jedną liczbę całkowitą , oznaczającą liczbę drzew w sadzie. Kolejny wiersz zawiera ciąg liczb całkowitych , gdzie oznacza rodzaj -tego drzewa: 0 - oznacza gruszę, 1 - oznacza jabłoń. Można założyć, że w sadzie rośnie co najmniej jedna grusza i co najmniej jedna jabłoń.

Wyjście
Pierwszy i jedyny wiersz wyjścia powinien zawierać jedną liczbę całkowitą, równą maksymalnej odległości pomiędzy gruszą a jabłonią.

Przykład
Dla danych wejściowych:

5
0 1 1 0 0
poprawną odpowiedzią jest:

3

3

A. Od razu lepiej.

Tak na pierwszy rzut oka, odpowiedzią jest maksimum z następujących możliwości: pozycji ostatniej liczby przeciwnej do pierwszej liczby oraz długości ciągu minus jeden pomniejszonej o pozycję pierwszej liczby przeciwnej do ostatniej liczby.

W zadanym przykładzie, pierwsza wartość to dwa (pierwszą liczbą jest zero, ostatnia jedynka jest na pozycji 2); a druga to trzy (ostatnią liczbą jest zero, pierwsza jedynka występuje na pozycji 1, więc ostatecznie 5 - 1 - 1 = 3).

Innymi słowy, pierwsza wartość odpowiada odległości ostatniej jabłoni od pierwszej w ogóle gruszy, zaś druga wartość — pierwszej jabłoni od ostatniej w ogóle gruszy.

Jest kilka możliwości, żeby to zoptymalizować, ale najprostszym rozwiązaniem jest przelecenie tablicy w pętli, szukając pierwszej napotkanej wartości, która nam odpowiada.

0

Kolejny wiersz zawiera ciąg liczb całkowitych , gdzie oznacza rodzaj

Czegoś tu brakuje po "gdzie".

3

Indeks to jest numer komórki do której się odnosisz. Ty chyba myślisz, że to jest jej zawartość. Np w tablicy
0 1 1 0 0
masz kolejno indeksy
0 1 2 3 4

1

Fajnie, że chcesz przemyśleć program przed jego napisaniem, ale nie przesadź w drugą stronę. Po prostu zacznij go pisać i rozwiązuj problemy na bieżąco. Te zera i jedynki dobrze będzie trzymać w stringu, bo tutaj możesz użyć find, w linku masz też przykład użycia. Jeżeli napotkasz problem, spróbuj go wygooglać (takie zadanie występuje w wielu wariantach) albo napisz tutaj. Wklej kod, daj znać, co nie działa (albo źle działa) i pomyślimy. Ale najpierw musisz zacząć pisać, ziomekczku

0

Brute force będzie O(n^2), a pewnie nie o to chodziło.

0

@Althorion: mam problem właśnie z tym żeby ta pętla odtworzyła się tylko tyle razy co mówi i. Na razie mam takie coś, z czego mam problem z pętlą, jak powinna wyglądać.

cout << " Podaj ilosc drzew: ";
    cin >> i
    
    for(int t[ i ];-1<i<1000;++i)
2

Pętle w C++ wyglądają tak: for (instrukcja początkowa; warunek pętli; instrukcja po każdym kroku). U Ciebie instrukcja początkowa nie ma sensu (to tylko odwołanie do i-tego elementu tablicy, co patrząc na to, jak wyżej ustawiasz tę wartość, jest niepoprawne — n-elementowa tablica będzie miała indeksy od zera do n-1, czyli nie będzie miała elementu n-tego.

Po drugie, porównania w C++ się nie składają — zatem -1 < i < 1000 jest niepoprawne logicznie/składniowo (w zależności co chciałeś uzyskać). Być może poprawnym podejściem byłoby -1 < i && i < 1000, czyli sklejenie dwóch porównań koniunkcją.

Wreszcie po trzecie, jak masz pewną wartość i, którą chcesz ograniczyć pętlę, to jest to najczytelniej osiągane przez for (unsigned int k = 0; k < i; ++k) — wprowadzasz nową zmienną i to ją porównujesz ze swoim ograniczeniem.

0

Jak powinna wyglądać instrucja początkowa tego programu? Czy jakbym napisał t [ i-i ] to bym zaczął od indeksu 0?

2
KomnatoMan napisał(a):

Jak powinna wyglądać instrucja początkowa tego programu?

Nie chc em niczego czytać ale bendem programistom

2

Instrukcja początkowa to, jak sama nazwa wskazuje, instrukcja wykonywana na samym początku pętli, przed jej ciałem. Chcesz mieć tam coś, co Ci się przyda — odwołanie się do elementu tablicy niemal nigdy takim nie jest. Typowo umieszcza się tam inicjalizację licznika pętli, np. to słynne int i = 0;. Samo napisanie t[i - i] to to samo, co napisanie t[0], czyli „zajrzyj do zerowego elementu tablicy t”. No i sobie program zajrzy¹ — z czego nic więcej nie wyniknie…


¹ Tak, wiem, kompilator to wytnie jako no-op, ale nie chcę mu jeszcze bardziej mieszać… Załóżmy że kompiluje z -O0 ;).

0

Właśnie o to chodzi żeby zajrzał do indeksu 0, a to co tam znajdzie napisał na ekranie i obliczył ile znajduje się miejsc od innego np 0.

1

No to każ mu właśnie to zrobić — wypisanie na ekranie powinieneś znać, to std::cout << t[0]. Nie wiem dlaczego chcesz to mieć jako instrukcję początkową w pętli (drastycznie lepsze pod względem czytelności kodu jest umieszczanie w pętli tylko tych rzeczy, które bezpośrednio dotyczą tej właśnie pętli), ale to już Twoja decyzja.

0

Chodzi o to że pętla ma zaglądać w każdy indeks i w zależności co tam jest ma sie pokazywać zmienna jablon albo grusza, po to wstawiłem w instrucję początkową tablice t[ i ]

2

Pisałem Ci to już raz, ale napiszę drugi, bo może Ci umknęło: jeśli masz tablicę k-elementową, to najprostsza pętla iterująca kolejno po jej elementach wygląda tak:

for (unsigned int i = 0; i < k; ++i) {
    …
}

Gdzie za  wstawiasz instrukcje, które chcesz wykonywać. Czyli jak chcesz drukować wartość i-tego elementu, to to będzie po prostu:

for (unsigned int i = 0; i < k; ++i) {
    std::cout << t[i] << ' ';
}
0

Ja wiem że do tego jest poradnik w internecie, mianowicie losowe liczby. Ale sprawdzałem już 10 razy i mam tak samo linijke napisaną a ona jak na złość nie działa jak na filmie. Tak, mam dodanie odpowiednie biblioteki.

srand(time(NULL));
2

Na żadnym etapie tego problemu nie potrzebujesz generatora liczb pseudolosowych.

Oraz skoro korzystasz z C++, to korzystaj z C++ — a konkretnie, z <random>.

0

Jeżeli nie jesteś pewien, w jaki sposób działają pętle i jak z nimi pracować, zajrzyj TUTAJ. Daj sobie kilka dni na przerobienie materiału (przynajmniej części na początek), te tutoriale są zrobione w całkiem przyjemny sposób i dużo ci pomogą. Nic innego teraz nie zrobisz, nie przeskoczysz tych podstaw

5
tmk3 napisał(a):

Jeżeli nie jesteś pewien, w jaki sposób działają pętle i jak z nimi pracować, zajrzyj TUTAJ. Daj sobie kilka dni na przerobienie materiału (przynajmniej części na początek), te tutoriale są zrobione w całkiem przyjemny sposób i dużo ci pomogą. Nic innego teraz nie zrobisz, nie przeskoczysz tych podstaw

Zelent to przekleństwo internetu.
Uczy złych praktyk, ma poważne braki techniczne, prowadzące czasami do błędów, których od razu nie widać.
Niestety początkujący widzą w nim mesjasza programowania.
Tu jest ostatni raz jak się wysiliłem na rzeczową krytykę jednej z jego lekcji, ale takich kwiatków jest dużo więcej.
Co gorsza ktoś kiedyś na tym forum wspominał, że zgłaszał mu błędy i prosił o poprawę, a reakcja sprowadzała się do obrony własnej niekompetencji.

5

Potrzebujesz dwóch rzeczy, żeby rozwiązać ten problem:

  1. Nauczyć się podstaw C++.
  2. Wpaść na (dobry) algorytm, który rozwiąże ten problem.

Co do pierwszego — są źródła w sieci, są źródła książkowe… Trzeba Przysiąść, Przeczytać, Przyswoić i Przećwiczyć (zasada czterech Pe). Tego się nie przeskoczy — żeby programować, trzeba umieć programować…

Co do drugiego — tutaj gorzej, bo tego się z książek nauczyć nie da. Najlepsza metoda, jaką znam, to próbować, próbować i próbować, aż w końcu zaskoczy. Można się podeprzeć jakąś książkową wiedzą o algorytmice, bo wielokrotnie ciężko samemu wymyślić optymalne rozwiązania czy umieć dowieść ich poprawności/optymalności, ale do samego startu — tzn. umiejętności wymyślenia jakiegokolwiek działającego rozwiązania — nie jest to potrzebne.

Nawiasem mówiąc, dostałeś już tutaj ode mnie działający i optymalny¹ (w sensie złożoności algorytmicznej; da się go pewnie w praktyce sporo przyspieszyć, np. traktując ten ciąg zer i jedynek jako pojedynczą liczbę i używając sprytnie clz — ale to wymagać będzie benchmarkowania, a nie zakładania z góry) algorytm.


¹ Miałem chwilę pod prysznicem, żeby o tym pomyśleć i jestem w stanie przedstawić dowód, jak ktoś jest zainteresowany.

0

@Althorion: Dzień 2 zmagań, teraz mam taki problem, że pętla po spełnionym zadaniu wyłącza się. tj wykonuje się powiedzmy zamiast 10 razy tylko dwa razy, ponieważ za tym drugim spełnia się funcja if. Lepiej?

int n,a,k;
int main()
{
    cin >> n;
    cin >> a;
    for(int t[n];a<n-1;a++)
        if(a==1)
            cout<< k+1;
        else
            cout<< " ";

    return 0;
}

3

Nawet nie wiem, gdzie zacząć…

  1. Nie używaj zmiennych globalnych (pierwsza linijka).
  2. Nie używaj VLA — jeśli chcesz dynamicznie tworzone tablice, użyj std::vector.
  3. W ósmej linijce tworzysz jeszcze raz tablicę t, przykrywając tablicę t tworzoną w szóstej linijce.
  4. Na żadnym etapie nie wykorzystujesz tej tablicy.
  5. Za to masz jakieś odwołanie do k, które tylko tworzysz (i jako zmienna globalna jest wtedy od razu inicjowana domyślnie, czyli w przypadku inta — zerem) i wyświetlasz na ekranie…

Ogólnie, nie mam pojęcia nawet, co chciałeś zrobić.

EDYCJA: nie no, fajnie jest wrzucić kod, a potem go całkiem zmienić… To jest post do oryginalnego kodu, przed zmianami.


Dobra, wersja dla kodu po zmianach:

  1. Punkt pierwszy bez zmian — nie używaj zmiennych globalnych (pierwsza linijka).
  2. Punkt drugi bez zmian — nie używaj VLA — jeśli chcesz dynamicznie tworzone tablice, użyj std::vector (szósta linijka i deklaracja tablicy).
  3. Jeśli chcesz, żeby coś się wykonało dokładnie raz (siódma linijka), to czemu jest w pętli?
  4. Nigdzie nie wykorzystujesz swojej tablicy t.
  5. Zmienna k, jako zmienna globalna, jest inicjowana domyślnie (czyli, dla inta, którym jest — zerem). Nic z nią nie robisz, tylko używasz jej raz w ósmej linijce, gdzie równie dobrze mógłbyś zamiast k + 1 mieć po prostu 0 + 1 czy wręcz 1, na jedno by wyszło…

I, tak jak powyżej, w ogóle nawet nie mam pomysłu, co chciałeś tym kodem osiągnąć…

0

Tylko jak ja teraz mam to zrobić, ponieważ jak już przeczytałem ten tekst to albo jestem głupi i tak nie zauważyłem tego jak ja mam stworzyć albo nie ma tam tego.

  1. Nie używaj VLA — jeśli chcesz dynamicznie tworzone tablice, użyj std::vector.
    CodeBlocks mówi że "vector" nie jest częścią std, cokolwiek to znaczy
1

Czym jest „to”, które chcesz zrobić? Napisz tak dokładnie, jak tylko jesteś w stanie.

Chcesz zadeklarować wektor o długości ustalanej dynamicznie (tzn. w czasie działania programu)? To std::vector<int> nazwa_wektora(długość_wektora); Ci to zrobi.

0
  1. Punkt pierwszy bez zmian — nie używaj zmiennych globalnych (pierwsza linijka).
    Jak inaczej moge zadeklarować trzy zmienne które muszą być "zapełnione" na początku kodu?
  1. Jeśli chcesz, żeby coś się wykonało dokładnie raz (siódma linijka), to czemu jest w pętli?

Chcę żeby sie wykonało tyle razy ile jest indeksów w tablicy

  1. Nigdzie nie wykorzystujesz swojej tablicy t.
    W pętli wykorzystuje.
  1. Zmienna k, jako zmienna globalna, jest inicjowana domyślnie (czyli, dla inta, którym jest — zerem). Nic z nią nie robisz, tylko używasz jej raz w ósmej linijce, gdzie równie dobrze mógłbyś zamiast k + 1 mieć po prostu 0 + 1 czy wręcz 1, na jedno by wyszło…
    Zmienna k ma za zadanie przechować informacje o odległości między zerami

I, tak jak powyżej, w ogóle nawet nie mam pomysłu, co chciałeś tym kodem osiągnąć…
To już pisałem w komentarzu

3

Jak inaczej moge zadeklarować trzy zmienne które muszą być "zapełnione" na początku kodu?

Jako lokalne — wewnątrz funkcji main, w Twoim wypadku.

Chcę żeby sie wykonało tyle razy ile jest indeksów w tablicy

No to od tego jest pętla. Twój if się odpali dokładnie w jednej sytuacji — gdy a będzie równe jeden. A będzie równe co najwyżej jeden raz, bo zaczyna jakieś (przyjmujesz je od użytkownika w linijce piątej) i potem je zawsze zwiększasz o jeden, co iterację pętli.

W pętli wykorzystuje.

Nie wykorzystujesz. Nie masz nawet jednego odwołania do t. Jedyny moment, gdy ta się w ogóle w Twoim kodzie pojawia, to linijka szósta. Gdzie, korzystając z VLA (które nie jest częścią C++, ale niektóre kompilatory chcą być miłe i to łykają), tworzysz sobie tę tablicę. I to wszystko. Nic w niej nie zapisujesz, nic z niej nie odczytujesz, nic z nią nie robisz.

Zmienna k ma za zadanie przechować informacje o odległości między zerami

Ale tego nie robi. Komputer Ci nie jest w stanie przeczytać w myślach i odgadnąć Twoich zamiarów. Musisz mu to bardzo dokładnie wytłumaczyć, krok po kroku, bo komputer to absolutny idiota, który robi tylko to, co mu wcześniej pokażesz.

4

@KomnatoMan - w obecnym momencie brakuje Ci podstawowej wiedzy, dlatego nie jesteś w stanie napisać programu do rozwiązania tego problemu. Skupiłbym się na nauce podstaw programowania, przepisując przykłady z książek. Zauważ, że przez 3 strony ktoś tłumaczy podstawy programowania, a każda z merytorycznych odpowiedzi wymagała więcej wysiłku, niż zakodowanie rozwiązania. Szacunek, że komuś się chciało. Lepiej zainwestować ten czas w naukę od podstaw, a dopiero potem wrócić do takich zadanek.

0

@Althorion: Pisze, a bardziej próbuje napisać, program który:
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.
Program ma sprawdzać ile jest odstępów między napisanymi 0.

dokłądniej chodzi o to zadanie.

Wejście
Pierwszy wiersz wejścia zawiera jedną liczbę całkowitą (), oznaczającą liczbę drzew w sadzie. Kolejny wiersz zawiera ciąg liczb całkowitych , gdzie oznacza rodzaj -tego drzewa: 0 - oznacza gruszę, 1 - oznacza jabłoń. Można założyć, że w sadzie rośnie co najmniej jedna grusza i co najmniej jedna jabłoń.

Wyjście
Pierwszy i jedyny wiersz wyjścia powinien zawierać jedną liczbę całkowitą, równą maksymalnej odległości pomiędzy gruszą a jabłonią.

Przykład
Dla danych wejściowych:

5
0 1 1 0 0
poprawną odpowiedzią jest:

3

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