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

R. 45 Struktury - zadanie domowe ppkt a

Ostatnio zmodyfikowano 2020-01-04 21:47
Autor Wiadomość
Yumox
Temat założony przez niniejszego użytkownika
R. 45 Struktury - zadanie domowe ppkt a
» 2020-01-04 15:47:55
Cześć, czy funkcja napisana przeze mnie z zadania 1 w rozdziale struktury jest napisana poprawnie?
C/C++
void dodajPoczatek( Lista *& lista, int liczba )
{
    Lista * nowy = new Lista;
    nowy->liczba = liczba;
    if( lista == 0 )
         nowy->ogon = 0;
    else
         nowy->ogon = lista;
   
    lista = nowy;
}

W zadaniu 2 pisze aby nie odwiedzać wszystkich węzłów, a moja funkcja dodajPoczatek() ich nie odwiedza czyli muszę znaleźć tylko rozwiązanie dla funkcji dodajKoniec()?
P-175948
pekfos
» 2020-01-04 16:07:05
1. Tak
2. Czy cokolwiek w zadaniu 2 ma chociaż sens w odniesieniu do dodajPoczatek()? Jest jasno napisane, o jaką funkcję chodzi.
P-175949
Yumox
Temat założony przez niniejszego użytkownika
» 2020-01-04 16:18:47
Czy tak zmodyfikowana funkcja:
C/C++
void dodajKoniec( Lista *& lista, int liczba, Lista *& wskaznik )
{
    Lista * nowy = new Lista;
    nowy->liczba = liczba;
    nowy->ogon = 0;
    if( lista == 0 )
         wskaznik = lista;
   
    if( lista )
         ostatni( wskaznik )->ogon = nowy;
    else
         lista = nowy;
   
    wskaznik = nowy;
i program główny:
C/C++
int main()
{
    int liczba;
    Lista * lista = 0;
    Lista * wskaznik = 0;
    std::cout << "Podaj liczby, 0 lub blad konczy:\n";
   
    while( std::cin >> liczba && liczba )
         dodajKoniec( lista, liczba, wskaznik );
   
    std::cout << "Koniec, oto liczby:\n";
    wypisz( lista );
    zniszcz( lista );
}
są dobrym rozwiązaniem? W podpowiedzi pisało że może być potrzebna kolejna struktura, ale chyba nie jest to konieczne?
P-175950
pekfos
» 2020-01-04 17:24:37
Teraz opisujesz listę dwoma zmiennymi, które muszą być spójne by kod działał poprawnie. Lepszym rozwiązaniem jest opakowanie ich w drugą strukturę.
P-175953
Yumox
Temat założony przez niniejszego użytkownika
» 2020-01-04 17:38:39
Chodzi o takie coś? Utworzenie kolejnej struktury w której będzie wskaźnik na Lista?
C/C++
struct Listawsk
{
    Lista * wskaznik;
    Lista * lista;
};

czyli funkcja powinna wyglądać tak:
C/C++
void dodajKoniec( Lista *& lista, int liczba, Lista *& wskaznik )
{
    Lista * nowy = new Lista;
    nowy->liczba = liczba;
    nowy->ogon = nullptr;
    if( lista == nullptr )
         wskaznik = lista;
   
    if( lista )
         ostatni( wskaznik )->ogon = nowy;
    else
         lista = nowy;
   
    wskaznik = nowy;
   
}

a program główny tak?
C/C++
int main()
{
    int liczba;
    Listawsk obiekt;
    obiekt.wskaznik = nullptr;
    obiekt.lista = nullptr;
    std::cout << "Podaj liczby, 0 lub blad konczy:\n";
   
    while( std::cin >> liczba && liczba )
         dodajKoniec( obiekt.lista, liczba, obiekt.wskaznik );
   
    std::cout << "Koniec, oto liczby:\n";
    wypisz( obiekt.lista );
    zniszcz( obiekt.lista );
}

P-175954
pekfos
» 2020-01-04 18:15:03
C/C++
dodajKoniec( obiekt.lista, liczba, obiekt.wskaznik );
Po co zostawiasz tu możliwość podania błędnych argumentów? Wszystkie funkcje powinny przyjmować referencję na (stałą) strukturę opisującą listę, zamiast poprzedniego wskaźnika / referencji na wskaźnik.
P-175955
Yumox
Temat założony przez niniejszego użytkownika
» 2020-01-04 19:22:04
Wydaje mi się, że teraz rozwiązanie jest poprawne tylko funkcja wypisz() nie przyjmuje jako argumentu wskaźnika na tą nową strukturę bo przy wywołaniu rekurencyjnym wyskakuje błąd, że jest wskaźnik na nieodpowiedni typ.
C/C++
#include <iostream>
struct Lista;
struct Listawsk
{
    Lista * wskaznik;
    Lista * lista;
};
struct Lista
{
    Lista * ogon;
    int liczba;
};

// Wypisz wszystkie elementy listy
void wypisz( Lista * lista )
{
    // Przechodzenie po liœcie *rekurencyjnie*
    if( lista )
    {
        std::cout << lista->liczba << ", ";
        wypisz( lista->ogon );
    }
}


// Zwróæ: wskaŸnik na ostatni element listy
Lista * ostatni( Lista * lista )
{
    // Przechodzenie po liœcie *iteracyjnie*
    if( lista )
    while( lista->ogon )
         lista = lista->ogon;
   
    return lista;
}


// Dodaj element na koniec listy
void dodajKoniec( Listawsk * obiekt, int liczba )
{
    Lista * nowy = new Lista;
    nowy->liczba = liczba;
    nowy->ogon = nullptr;
    if( obiekt->wskaznik == nullptr )
         obiekt->wskaznik = nowy;
   
    if( obiekt->lista )
         ostatni( obiekt->wskaznik )->ogon = nowy;
    else
         obiekt->lista = nowy;
   
    obiekt->wskaznik = nowy;
}


// Usuwa listê
void zniszcz( Listawsk * obiekt )
{
    while( obiekt->lista )
    {
        Lista * tmp = obiekt->lista;
        obiekt->lista = obiekt->lista->ogon;
        delete tmp;
    }
   
    obiekt->lista = nullptr;
}


int main()
{
    int liczba;
    Listawsk obiekt;
    obiekt.wskaznik = nullptr;
    obiekt.lista = nullptr;
    std::cout << "Podaj liczby, 0 lub blad konczy:\n";
   
    while( std::cin >> liczba && liczba )
         dodajKoniec( & obiekt, liczba );
   
    std::cout << "Koniec, oto liczby:\n";
    wypisz( obiekt.lista );
    zniszcz( & obiekt );
}
P-175956
pekfos
» 2020-01-04 21:21:04
teraz rozwiązanie jest poprawne tylko funkcja wypisz() nie przyjmuje jako argumentu wskaźnika na tą nową strukturę bo przy wywołaniu rekurencyjnym wyskakuje błąd, że jest wskaźnik na nieodpowiedni typ.
To trzeba zmienić implementację. Przestało być wygodnie z rekurencją, to można ją wywalić i zrobić iteracyjnie - jak powinno być zresztą od samego początku. W kursie ta rekurencja jest użyta tylko dla demonstracji i oswajania z konceptem, a nie dlatego że wypisywanie listy, z jakiegoś niewyjaśnionego w kursie powodu, musi być zrobione akurat rekurencyjnie.

Powiedzmy, że jest ok. Będę musiał pewnie przerobić tą lekcję, żeby krok ze wstawieniem nowej struktury już był zrealizowany jako drugi przykład. Jak dotąd każdy temat dotyczący tego zadania ma jakieś dziwne rozwiązanie, typu dorzucony bez ładu i składu nowy argument. Tu nie jest inaczej. Bez trudu można by wywalić w powietrze twoje trójargumentowe dodajKoniec() jeśli pierwszy element listy doda się funkcją dodajPoczatek() ;)
A może trzeba dorzucić wymaganie, by lista trzymała informację o swojej długości? Może kolejny argument do funkcji dodającej by był wystarczającym impulsem by pomyśleć o użyciu wiedzy z bieżącej lekcji?
P-175957
« 1 » 2
  Strona 1 z 2 Następna strona