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

Tablica (pl spoj) błędna odpowiedź mimo poprawnego rozwiązania

0 głosów
182 wizyt
pytanie zadane 31 sierpnia 2021 w SPOJ przez n0sk1llexe Początkujący (300 p.)
zmienione kategorie 2 września 2021 przez ScriptyChris

Zadanie TABLICA
Przeszukałem dość sporo tematów (zarówno tutaj, jak i na forum spoja) i w dalszym ciągu nie mogę znaleźć odpowiedzi, dlaczego kod z dynamiczną tablicą jest odrzucany.

Poprawne rozwiązanie #TablicaStatyczna
 

#include <iostream>

using namespace std;

int main()
{
    int liczba;
    int tab[100];
    int i = 0;
    while (cin >> liczba)
    {
        tab[i] = liczba;
        i++;
    }
    for (i >= 0; i--;)
    {
        cout << tab[i] << endl; //kod został akceptowany mimo braku rozdzielenia spacjami
    }
    return 0;
}

Błędna odpowiedź #TablicaDynamiczna

#include <iostream>

using namespace std;

int main()
{
    int liczba;
    int x = 1;
    int i = 0;
    int *tab = new int[x];
    while (cin >> liczba)
    {
        tab[i] = liczba;
        i++;
        x++;
    }
    for (i >= 0; i--;)
    {
        cout << tab[i] << " "; 
    }
    delete [] tab;
    return 0;
}

Proszę o jakieś sugestie, albo wyjaśnienia co jest źle w przypadku drugiego kodu skoro zawracane odpowiedzi są identyczne

1
komentarz 31 sierpnia 2021 przez TOM_CPP Pasjonat (22,620 p.)

Pierwszy przykład kodu też nie jest poprawny, gdyż pozwala na wpisanie dowolnej liczby elementów do tablicy, która ma ograniczoną pojemność. Jak ją przekroczysz to masz UB

komentarz 31 sierpnia 2021 przez n0sk1llexe Początkujący (300 p.)

No tak, linijka nr 10 powinna wyglądać w ten sposób:

while (cin >> liczba && i < 100)

Nie mniej jednak w tym zadaniu założyłem, że liczba elementów nie przekroczy 100.

1 odpowiedź

+1 głos
odpowiedź 31 sierpnia 2021 przez Whiskey_Taster Stary wyjadacz (13,620 p.)
Tylko Ci się wydaje, że oba kody są poprawne. W przypadku dynamicznej tablicy tak w zasadzie tworzysz tablicę jednoelementową, a potem odwołujesz się do nieistniejących elementów tej tablicy. Pamięć dla tablicy przydzielasz tylko raz, w linii nr 10, potem zupełnie nic nie robisz w kierunku powiększenia tablicy. To, że sobie zwiększasz zmienną 'x' nie oznacza, że magicznie zwiększysz ilość komórek tablicy. Tak naprawdę to, co napisałeś jest równorzędne zadeklarowaniu zwykłej tablicy jednoelementowej.
komentarz 31 sierpnia 2021 przez n0sk1llexe Początkujący (300 p.)
edycja 31 sierpnia 2021 przez n0sk1llexe
Rozumiem, a czy jest jakiś sposób (poza użyciem std::vector<>) na utworzenie powiększającej? Z racji braku doświadczenia na ten moment do głowy przychodzi mi tylko rekurencyjny void, który po otrzymaniu zmiennej sygnalizowałby konieczność przekopiowania aktualnej tablicy[n] oraz utworzenia nowej [n+1]. Ale strasznie to prymitywne i czy w ogóle miałoby szansę zadziałać
1
komentarz 31 sierpnia 2021 przez Oscar Nałogowiec (25,750 p.)
Mógłbyś dać link do treści zadania? Być może tam wcale nie chodzi o tablicę. Wczytujesz liczby, potem je wypisujesz od tyłu. To można zrobić np. rekurencją bez żadnej tablicy (liczby będą na stosie). Albo użyć jakiejś listy - dostęp masz czysto sekwencyjny.
komentarz 31 sierpnia 2021 przez n0sk1llexe Początkujący (300 p.)
edycja 31 sierpnia 2021 przez n0sk1llexe
Zapomniałem dać link, już edytowałem post.
komentarz 31 sierpnia 2021 przez Whiskey_Taster Stary wyjadacz (13,620 p.)

@n0sk1llexe, ogółem, jeśli chodzi o tablice, to po prostu musisz stworzyć tablicę o większej pojemności, przekopiować wartości do nowej tablicy, a starą tablicę usunąć. 

komentarz 2 września 2021 przez n0sk1llexe Początkujący (300 p.)
edycja 2 września 2021 przez n0sk1llexe

Myślałem o takiej funkcji, tylko pojawił się kolejny problem. Mianowicie nie wiem czy jest to możliwe aby w środku funkcji, po wykonaniu instrukcji zastąpić tablicę tab, nową tablicą nTab (w przypadku gdybym chciał funkcję wykorzystać rekurencyjnie i powiększyć tablice o kilka komórek) no i przede wszystkim czy da się wtedy zwrócić do maina taką tablicę utworzoną w ciele funkcji.
 

int powiekszTab (int *tab; int d; int v)
//d - dlugosc tablicy
//v - wartość komórki, która ma zostać dodana
{
    int nTab[d+1];
    for (int i = 0; i < d; i++)
    {
        nTab[i] = tab[i];
    }
    nTab[d] = v;
}

 

1
komentarz 2 września 2021 przez Oscar Nałogowiec (25,750 p.)

Tablica nTab jest lokalna w funkcji i nie "wychodzi" na zewnątrz. Jesli chcesz powiększać tablicę musisz to robić allokacją dynamiczną (new). I nie powiększaj tablicy co 1 tylko np. dwukrotnie - oczywiście musisz sam pilnować długości (czy jeszcze starcza i ile jest zaallokowane).

Nie bardzo rozumiem co rozumiesz przez "rekurencję" w tym momencie. Odwracanie kolejności jak najbardziej może być wykonane rekurencyjnie (szczególnie, że w zadaniu podano, że liczba danych jest "niewielka" co sygeruje, że nie trzeba użyć całej pamięci komputera, stos wystarczy.

void odwracanieRekurencyjne()
{
    int liczba;
    if (cin >> liczba)
    {
        // udalo się wczytać
        odwracanieRekurencyjne();
        cout << liczba << endl;
    }
}

W takim rozwiązaniu kolejne liczby pamiętane są w zmiennych "liczba" na kolejnych poziomach rekurencji.

No ale zadanie nazywa się TABLICA, więc pewnie nie o to chodziło.

komentarz 3 września 2021 przez n0sk1llexe Początkujący (300 p.)

Dziękuję za ciekawego voida.
Źle zbudowałem swoją wypowiedź, bardziej chodziło mi zapętlenie powiększania tablicy o 1, cały czas dopóki użytkownik będzie wprowadzać dane (v). Pierwotnie myślałem o rekurencji, ale nie wiedzieć czemu poszedłem w stronę pętli. Miałem problem z nTab jako zmienną lokalną i wiedziałem, że raczej nie da się tego zwrócić do maina(no chyba, że istnieje na to jakiś sposób).
 

int dlugosc = x; //dowolna liczba, wstawiam 'x' dla zobrazowania o co mi chodziło
while (cin >> liczba)
    {
//teraz przemyślałem tą funkcję, no i gdyby była w takiej konstrukcji to i tak zawsze ostatnia komórka musiałaby być tworzona na zapas
            powiekszTab (tab; x; liczba); //ta funkcja wykonałaby się maks. 1 raz, gdyż później nie wykonałaby się dla tablicy nTab, która i tak by nie wyszła do maina
    }

 

Podobne pytania

0 głosów
2 odpowiedzi 148 wizyt
0 głosów
0 odpowiedzi 196 wizyt
0 głosów
1 odpowiedź 204 wizyt
pytanie zadane 19 lipca 2018 w SPOJ przez Piotr Błaszczak Bywalec (2,890 p.)

88,355 zapytań

136,952 odpowiedzi

305,666 komentarzy

58,618 pasjonatów

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.

...