Programowanie strukturalne c++, listy, i ich implementacje

0

Witam, wiem że komuś może się to wydać proste ale ja właśnie mam z tym problem. Nie wiem jak zabrać się za zadanie z list jednokierunkowych. Przytaczam treść zadania i poniżej to co wykombinowałam sama. Bardzo proszę o w miarę szybką odpowiedź.
zad.8
Napisać funkcję, która do listy jednokierunkowej zawierającej pary (znak, liczba) i zaczynającej się pod jakimś adresem jako drugi dopisuje element o jakichś danych, gdy na liście są wyłącznie elementy zawierające małe litery w polu znakowym, po czym zwraca adres dopisanego elementu lub NULL, gdy niczego nie dopisano.
Funkcję poprzedzić definicją odpowiedniej struktury.
Uwaga: Słowo jakiś oznacza parametr funkcji.

Już na wstępie mam problem jak przekazać parametr struktury o więcej niż jednym polu. (oprócz wskaźnika)
Oto moje wypociny:

#include <cstdlib>


using namespace std;

struct element_listy
{
    char znak;
    int liczba;
    element_listy *wsk_nastepnika;
};

//iteracyjna funkcja drukujaca zawartosc listy
void drukuj(element_listy *adres)
{
    while(adres!=NULL)
    {
        cout<<adres->liczba<<" "<<adres->znak<<endl;
        adres=adres->wsk_nastepnika;
    }
}

element_listy funkcja8(element_listy* adres, element_listy* co)
{
    element_listy* tmp;
    tmp=adres->wsk_nastepnika;
    adres->wsk_nastepnika=co;
    co->wsk_nastepnika=tmp;

}

int main()
{
    //zmienne do obslugi listy - wszystkie to wskazniki
    element_listy *glowa, *aktualny, *poprzedni, *tmp;
    //dodatkowe dane pomocnicze
    int liczba, ile, ilew, i;
    char znak;

    //Tworzenie listy, zero konczy wpisywanie
    aktualny=NULL;
    poprzedni=NULL;
    glowa=poprzedni;
    cout<<"Podaj liczbe do wstawienia:";
    cin>>liczba;
    cout<<"Podaj znak do wstawienia: ";
    cin>>znak;
    while(liczba!=0)
    {
        //zapamietujemy dotychczasowy koniec listy
        poprzedni=aktualny;
        //tworzymy nowy element
        aktualny=new element_listy;
        //zapisujemy do niego odczytane dane
        aktualny->liczba=liczba;
        aktualny->znak=znak;
        //teraz jest to ostatni element listy;
        aktualny->wsk_nastepnika=NULL;
        //poprzedni ostatni juz nie jest ostatnim
        if(poprzedni!=NULL)
            poprzedni->wsk_nastepnika=aktualny;
        else glowa=aktualny;

        //i odczytujemy nowe dane
        cout<<"Podaj liczbe do wstawienia: ";
        cin>>liczba;
        cout<<"Podaj znak do wstawienia: ";
        cin>>znak;
    };
    cout<<"Po wprowadzeniu wydruk listy:\n";
    drukuj(glowa);
    funkcja8(glowa,liczba,znak);
    drukuj(glowa);

//zwalnianie pamieci
aktualny=glowa;
while(aktualny!=NULL)
{
    poprzedni=aktualny;
    aktualny=aktualny->wsk_nastepnika;
    delete poprzedni;
}
cout<<"\n Pamiec zwolniona\n";

    return 0;
}

Prosiłabym o podpowiedzi w c++ ale strukturalnym który obowiązuje mnie na egzaminie. (Nie obiektowym)

Z góy dziękuję za pomoc i pozdrawiam

2

Teraz masz:

zuzannaruda napisał(a):

Napisać funkcję, która do listy jednokierunkowej

  1. zawierającej pary (znak, liczba)
  2. i zaczynającej się pod jakimś adresem
  3. jako drugi dopisuje element
  4. o jakichś danych,
  5. gdy na liście są wyłącznie elementy zawierające małe litery w polu znakowym,
  6. po czym zwraca adres dopisanego elementu lub NULL, gdy niczego nie dopisano.
  7. Funkcję poprzedzić definicją odpowiedniej struktury.
  1. Patrz 7.
  2. Jest.
  3. Dopisanie jednego elementu można zaimplementować jako oddzielną funkcję. Do zrobienia.
  4. Jest.
  5. Trzeba przejść przez całą listę i sprawdzić podany warunek (najlepiej jako oddzielna funkcja). Wtedy (w zależności od warunku) wywołać funkcję z 3. lub zwrócić NULL. Do zrobienia.
  6. Teraz zwraca element a nie adres elementu. Do poprawienia.
  7. Jest.
0

Dziękuję z szybką odpowiedź. Jednak dopiero teraz mogłam się za nie zabrać. Jeżeli dobrze zrozumiałam zadanie to musi się ono zawierać w jednej funkcji. Nad resztą pracuję. Wkrótce spróbuję coś dodać.

0

Nie do końca; jeśli sama Tworzysz strukture, to Musisz mieć funkcje: dodająca elementy do listy (tworzącą ją), funkcję dodającą element na drugim miejscu, a ta będzie korzystała z trzeciej - sprawdzającej czy można dodać; przydałby się jeszcze destruktor (usunięcie listy).

0

@zuzannaruda: Ogólnie więcej funkcji to lepiej (do pewnej rozsądnej liczby funkcji :)) -- nie wyobrażam sobie rozsądnego nauczyciela, który karze za definiowanie dodatkowych funkcji pomocniczych.

0

Dziękuję za szybką odpowiedź. Nieco poprawiłam ale niestety mam nadal problemy z warunkiem "czy jest to mała litera". Proszę zerknąć co mam nie tak.
Z góry dziękuję za pomoc.

#include <iostream>
#include <cstdlib>


using namespace std;

struct element_listy
{
    char znak;
    int liczba;
    element_listy *wsk_nastepnika;
};

//iteracyjna funkcja drukujaca zawartosc listy
void drukuj(element_listy *adres)
{
    while(adres!=NULL)
    {
        cout<<adres->liczba<<" "<<adres->znak<<endl;
        adres=adres->wsk_nastepnika;
    }
}

// Zwróæ: wskaŸnik na ostatni element listy
element_listy* ostatni( element_listy* adres )
{
    // Przechodzenie po liœcie *iteracyjnie*
    if( adres )
    while( adres->wsk_nastepnika )
         adres = adres->wsk_nastepnika;

    return adres;
}


// Dodaj element na koniec listy
void dodajKoniec( element_listy *& adres, int liczba, char znak )
{
    // Tworzymy nowy element listy
    element_listy * nowy = new element_listy;
    nowy->liczba = liczba;
    nowy->znak = znak;
    nowy->wsk_nastepnika = NULL;

    // Dopisujemy na koniec
    if( adres )
         ostatni( adres )->wsk_nastepnika = nowy;
    else
         adres = nowy;

}

// Usuwa listê
void zniszcz( element_listy *& adres )
{
    while( adres )
    {
        element_listy * tmp = adres;
        adres = adres->wsk_nastepnika;
        delete tmp;
    }

    adres = NULL;
}


void wstaw(element_listy* adres, element_listy* co)
{
    element_listy* tmp;
    tmp=adres->wsk_nastepnika;
    adres->wsk_nastepnika=co;
    co->wsk_nastepnika=tmp;

}
element_listy* funk8(element_listy* adres, char znak)
{
    while(adres!=0)
    {

        if ((znak > 47) && (znak < 58)) cout << "Jest to cyfra." << endl;
        else if ((znak > 96) && (znak < 123)) cout << "Jest to mala litera." << endl;
        else if ((znak > 64) && (znak < 91)) cout << "Jest to duza litera." << endl;
        adres=adres->wsk_nastepnika;
    }



}

int main()
{
    int liczba;
    char znak;
    element_listy* adres = NULL;

    cout << "Podaj liczbe i znak, 0 lub blad konczy:\n";

    while( liczba!=0)
    {
        cin >> liczba >> znak;
        dodajKoniec( adres, liczba, znak );
    }
    //cout << "Koniec, oto liczby:\n";
    drukuj( adres );
    element_listy * co = new element_listy;
    co->liczba=5;
    co->znak='@';
    //nowy->wsk_nastepnika = NULL;


    wstaw(adres, co);
    drukuj(adres);
    funk8(adres,znak);
    zniszcz( adres );
  return 0;
}
0

Po co tak, w cctype jest islower .

0

Proszę o bardziej konkretny przykład, bo sama do tego nie dojdę. Uczę się praktycznie sama i potrzebuję jakiegoś wzoru.
Przesyłam to co spłodziłam sama. Dzięki za pomoc.

element_listy* funk8(element_listy* adres, element_listy* to)
{
    element_listy * co = new element_listy;
    co->liczba=5;
    co->znak='@';
    while(adres!=0)
    {

        if (islower(to->znak)) wstaw(adres, co);
        adres=adres->wsk_nastepnika;
    }



}```
0

No i co się dzieje?

0

O to chodzi że nic się nie dzieje. Nic nie wstawia. Nie wiem jak przekazać argumenty z jednej do drugiej funkcji.

0

Debugowałaś to?

0

Nie, w pracy nie mam debugera. Muszę go dodać.

0

Trzeba to zdebugować; widze tez jedna głupotę, czemu w liście jednokierunkowej, Masz dodawanie na koniec, a nie na poczatek?

0

A co to za różnica czy dodaję na końcu czy na początku?

0

A co to za różnica czy dodaję na końcu czy na początku?

No taka, że marnujesz czas na dostęp do wszystkich elementów listy.

0

Złożoność, na końcu: ~n, na początku: ~const.

0

Mam prośbę żeby skupić się na tej funkcji która jest w poleceniu. Na chwilę obecną reszta to tylko oprawa dla niej żebym mogła sprawdzić czy działa.Ale dzięki za sugestie. Na przyszłość wezmę pod uwagę. Reszta funkcji działa poprawnie więc na razie ich nie poprawiam.

0

Debugowałam i nie wykazuje żadnych błędów.
Przerobiłam ale dodaje element na ostatnim miejscu zamiast na drugim:

element_listy* funk8(element_listy* adres)
{
    element_listy * co = new element_listy;
    co->liczba=5;
    co->znak='@';
    while(adres!=0)
    {

        if (islower(adres->znak)) wstaw(adres, co);
        adres=adres->wsk_nastepnika;
    }



}

screenshot-20200118131455.png

0

Dzięki wielkie za pomoc.
Niby wstawia ale drukuje drugi raz tylko do nowowstawionego a nie całą listę.

0

Zrób funkcję która zwróci true gdy na liście będą tylko elementy z małymi literami, false gdy przynajmniej jeden nie będzie spełniał tego warunku.
Zrób funkcję która dopisze element za pierwszym elementem listy (w parametrach niech przyjmuje dane do wpisania do elementu).
W Twojej funkcji użyj tych dwóch napisanych.

0

Niby wstawia ale drukuje drugi raz tylko do nowowstawionego a nie całą listę.

Zdebuguj dokładnie, Odcinasz gdzieś wskaźnik na przód.

0

Oto funkcja wstawiająca:

void wstaw(element_listy* adres, int liczba, char znak)
{
    element_listy* tmp;
    element_listy* co = new element_listy;
    co->liczba=liczba;
    co->znak=znak;
    tmp=adres->wsk_nastepnika;
    adres->wsk_nastepnika=co;
    co->wsk_nastepnika=tmp;
}
//to moja boolowska:
bool mlitery(element_listy* adres)
{
    while(adres)
    {
     if (islower(adres->znak))
            return true;
     else return false;
     adres=adres->wsk_nastepnika;
    }

}

Prośba o sprawdzenie.
Nie wiem też jak można ich użyć. Coś podobnego do poniższego? Tylko proszę o wyrozumiałość bo nie kminię dobrze jeszcze list.

element_listy* funk8(element_listy* adres)
{
  
if(mlitery(adres)==true) wstaw(adres, liczba, znak);

}
0

Pierwszą funkcję można krócej:

void wstaw(element_listy* adres, int liczba, char znak)
{
    element_listy* co = new element_listy;
    co->liczba=liczba;
    co->znak=znak;
    co->wsk_nastepnika=adres->wsk_nastepnika;
    adres->wsk_nastepnika=co;
}

W drugiej wartość true zwróć gdy masz pewność, że każdy element listy pasuje czyli dopiero na końcu.
A w funk8() zapomniałaś o zwracaniu wartości.

0

Udało mi się skończyć zadanie. Dziękuję wszystkim za pomoc.
Temat uważam za zamknięty.

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