Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

R. 45 - zadanie domowe - pytanie do ppkt b

Ostatnio zmodyfikowano 2019-09-17 20:14
Autor Wiadomość
rottingham
Temat założony przez niniejszego użytkownika
» 2019-08-01 22:16:44
Ok.

A dlaczego w argumencie funkcji wypisz jest słowo kluczowe const? Czy to jest potrzebne do stworzenia dobrego rozwiązania?
P-174966
pekfos
» 2019-08-01 22:20:29
Nie. Po prostu logiczne jest, że wypisywanie listy nie wymaga jej modyfikowania.
P-174967
rottingham
Temat założony przez niniejszego użytkownika
» 2019-08-21 20:55:44
Czy jest sensowne, żeby w struct stworzyć trzecią składową przechowującą adres ostatniego elementu? Próbuję jakoś w ten sposób, ale nie wychodzi mi. Tzn. kod dodaje element na koniec listy, ale w liście znajduje się tylko pierwszy i ostatni element. Czy ten kod da się jakoś dopieścić czy to kompletnie nie tędy droga?

C/C++
#include <iostream>

using namespace std;

struct Wezel
{
    int liczba;
    Wezel * ogon;
    Wezel ** adres;
};

typedef Wezel * Lista;

void utworz( Lista & lista )
{
    lista = nullptr;
}

void dodajKoniec( int liczba, Lista & lista )
{
    Lista nowy = new Wezel;
    nowy->liczba = liczba;
    nowy->ogon = nullptr;
    nowy->adres = &( nowy->ogon );
   
   
   
    if( !lista )
    {
        lista = nowy;
    }
    else
    {
        *( lista->adres ) = nowy;
    }
}

void wypisz( const Lista lista )
{
   
    if( lista )
    {
        cout << lista->liczba << " ";
        wypisz( lista->ogon );
    }
}

void zniszcz( Lista & lista )
{
    while( lista )
    {
        Lista tmp = lista;
        lista = lista->ogon;
        delete tmp;
    }
   
    lista = nullptr;
}

int main()
{
    int liczba;
    Lista lista;
    utworz( lista );
   
    while( cin >> liczba && liczba )
         dodajKoniec( liczba, lista );
   
    wypisz( lista );
    zniszcz( lista );
}
P-175081
pekfos
» 2019-08-21 21:16:28
Czy jest sensowne, żeby w struct stworzyć trzecią składową przechowującą adres ostatniego elementu?
Może gdy rozważamy tylko dodawanie elementów do listy nie jest to kompletnie niepraktyczne, jednak wciąż nie powiedziałbym że jest to sensowne. Wezel ma już wszystko czego potrzeba, raczej powinieneś zmienić znaczenie Lista.
Podpowiedź: Możesz potrzebować drugiego struct.
P-175082
rottingham
Temat założony przez niniejszego użytkownika
» 2019-08-26 13:25:59
Hemm... Udało mnie się napisać taki kod. Co myślicie o tym? Będę wdzięczny za wszelkie uwagi i wskazówki.

C/C++
#include <iostream>

using namespace std;

struct Wezel
{
    int liczba;
    Wezel * ogon;
};

struct Lista
{
    Wezel * poczatek = nullptr;
    Wezel * koniec = nullptr;
};

void dodajKoniec( Lista & lista, int liczba )
{
    Wezel * element = new Wezel;
    element->liczba = liczba;
    element->ogon = nullptr;
   
    if( !lista.poczatek )
    {
        lista.poczatek = element;
        lista.koniec = element;
    }
    else
    {
        lista.koniec->ogon = element;
        delete lista.koniec;
        lista.koniec = nullptr;
        lista.koniec = element;
    }
   
}

void wypisz( Lista lista )
{
    while( lista.poczatek )
    {
        cout << lista.poczatek->liczba << " ";
        lista.poczatek = lista.poczatek->ogon;
    }
}

void zniszcz( Lista & lista )
{
    while( lista.poczatek )
    {
        Wezel * tmp = lista.poczatek;
        delete tmp;
        lista.poczatek = lista.poczatek->ogon;
    }
    lista.poczatek = nullptr;
   
    while( lista.koniec )
    {
        Wezel * tmp = lista.koniec;
        delete tmp;
        lista.koniec = lista.koniec->ogon;
    }
    lista.koniec = nullptr;
}

int main()
{
    int liczba;
    Lista lista;
   
    while( cin >> liczba && liczba )
         dodajKoniec( lista, liczba );
   
    wypisz( lista );
    zniszcz( lista );
}
P-175125
pekfos
» 2019-08-26 17:51:14
To w ogóle działa? Nie wygląda..
P-175126
rottingham
Temat założony przez niniejszego użytkownika
» 2019-08-26 19:29:16
Jak mogę rozpoznać, że ten kod nie działa?

Wrzucając tego maina:

C/C++
int main()
{
    Lista lista1, lista2;
    dodajKoniec( lista1, 1 );
    dodajKoniec( lista2, 2 );
    dodajKoniec( lista1, 3 );
    dodajKoniec( lista2, 4 );
    wypisz( lista1 );
    std::cout << '\n';
    wypisz( lista2 );
    zniszcz( lista1 );
    zniszcz( lista2 );
}

otrzymuję na wyjściu:

1 3
2 4

W związku z tym program pozornie jest w stanie zrobić dwie niezależne listy... Zatem dlaczego on nie działa?
P-175127
pekfos
» 2019-08-26 20:19:50
Ja skopiowałem Twój kod, podałem na wejście
1 2 3 4 5 6 0
 i dostałem
11543872 11544368 11534672 11674768 11561008 11543872 11544368 11534672 11674768 11561008 11543872 11544368 11534672 11674768 11561008 11543872 11544368 11534672 11674768 11561008 11543872 11544368 11534672 11674768 11561008 11543872 11544368 11534672
itd..
Trochę formalność, bo jak pisałem: kod nawet nie wygląda poprawnie. Jaka logika stała za tym, że dodajKoniec() alokuje jeden węzeł i zwalnia inny? Mam teorię: chcesz zwolnić wszystkie wskaźniki jakie masz, a powinieneś zwalniać wszystkie alokacje jakie wykonujesz (w swoim czasie naturalnie). Z jakiego innego powodu byś implementował niszczenie listy 2 razy - raz zaczynając od początku i raz od końca? Robisz z dodania tego dodatkowego wskaźnika znacznie większy problem, niż jest wart. Wystarczy go tylko w jednym miejscu ustawiać i w drugim wykorzystywać. Oba miejsca są w tej samej funkcji.
P-175129
1 2 « 3 » 4 5 6
Poprzednia strona Strona 3 z 6 Następna strona