Pevne dany linearne spojovy seznam a ukoly – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Pevne dany linearne spojovy seznam a ukoly – C / C++ – Fórum – Programujte.comPevne dany linearne spojovy seznam a ukoly – C / C++ – Fórum – Programujte.com

 

haha0
Newbie
27. 1. 2015   #1
-
0
-

Ahojte, mám problém. Zítra jdu na poslední opravny pokus z programování v C++ a nějak to prostě nechápu. Máme daný spojový seznam a jen v tom udělat nějaký úkol. Chtěl jsem se zeptat, jak by vypadalo, kdybych měl:

a) vypočítat BMI

b) vypsat jen lidi, jejichž jméno začíná na A

c) najít poslední zadaný prvek (vek) a vypsat jen to

Je tady někdo, kdo by mi prosím pomohl? Děkuji. (Tyhle úkoly už byly, jen bych chtěl vědět, jak to mám udělat. Snad bych to lépe pochopil.)

Kód:

#include <iostream>
#include <stdlib.h>

using namespace std;

struct Clovek {
    short vek;
    float vaha;
    char jmeno[50];
    Clovek* dalsi;
};


void vypisCloveka(Clovek c)
{
    cout << c.vek << endl;
    cout << c.vaha << endl;
    cout << c.jmeno << endl;
}

void vypisNtehoCloveka(Clovek prvni, int N)
{
    if (N <= 0)
    {
        vypisCloveka(prvni);
    }
    else
    {
        Clovek* current = prvni.dalsi;
        for (int i = 1;i < N;i++)
        {
            if (current->dalsi != nullptr) // Nejsme na poslednim vagone?
            {
                current = current->dalsi; // Prechod k dalsimu vagonku
            }
            else
            { // Jsme na poslednim
                cout << "N je vetsi nez delka spojoveho seznamu" << endl;
                return;
            }
        }
        vypisCloveka(*current);
    }
}

void vlozDoSeznamu(Clovek* loko, Clovek* kdo) // Vlozi clovek "kdo" do spojoveho seznamu zacinajici "loko"
{
    Clovek* current = loko;
    while (current->dalsi != nullptr) // Dojde k poslednimu prvku seznamu
    {
        current = current->dalsi;
    }

    // Pripoji "kdo" za posledni prvek => "kdo" se stava poslednim prvkem
    current->dalsi = kdo;
    kdo->dalsi = nullptr;
}

int spocitejPrvky(Clovek prvni)
{
    int pocitadlo = 1;

    Clovek* current = &prvni;
    while (current->dalsi != nullptr)
    {
        pocitadlo = pocitadlo+1; // to stejne jako pocitadlo++
        current = current->dalsi;
    }

    return pocitadlo;
}

void vypisCelySeznam(Clovek prvni)
{
    Clovek* current = &prvni;
    do //Pouzijeme do-while aby se vypsal i prvni prvek (je-li v seznamu jediny)
    {
        vypisCloveka(*current);
            current = current->dalsi;
    }
    while (current->dalsi != nullptr);

    // Musime vypsat jeste toho posledniho
    vypisCloveka(*current);
}

Clovek* vratNtehoCloveka(Clovek* loko,unsigned int N)
{
    
    int pocitadlo = 1;
    
    Clovek* current = loko;
    while (current->dalsi != nullptr && pocitadlo != N) // dokud nejsme na konci a jeste jsme nedosahli N
    {
        pocitadlo = pocitadlo+1; // to stejne jako pocitadlo++
        current = current->dalsi;
    }
    
    return current;
}

void odstranZeSeznamu(Clovek* loko, int kolikaty)
{
    int pocetPrvku = spocitejPrvky(*loko);

    // Odstranujeme prvek nekde uvnitr vlaku?
    if (kolikaty > 1 && kolikaty < pocetPrvku)
    {
        Clovek* tenCoMazu = vratNtehoCloveka(loko,kolikaty);
        Clovek* tenPredNim = vratNtehoCloveka(loko, kolikaty-1);
        Clovek* tenZaNim = vratNtehoCloveka(loko, kolikaty+1);

        tenPredNim->dalsi = tenZaNim;

        delete tenCoMazu;
    }

    // Jsme na poslednim vagonu a je tam vic vagonu nez jen loko?
    if (kolikaty == pocetPrvku && pocetPrvku > 1)
    {
        Clovek* tenCoMazu = vratNtehoCloveka(loko,kolikaty);
        Clovek* tenPredNim = vratNtehoCloveka(loko, kolikaty-1);
        
        tenPredNim->dalsi = nullptr;
        delete tenCoMazu;
    }
}


void smazCelySeznam(Clovek* loko)
{

    Clovek* current = loko;
    while (current->dalsi != nullptr)
    {
        // Pozor abych si nesmazal neco, co jeste potrebuju
        Clovek* tenCoMazu = current;
        current = current->dalsi;
        delete tenCoMazu;
    }

    delete current;
}


void nactiCloveka(Clovek* kdo)
{
    cout << "Zadejte vek cloveka: " << endl;
    cin >> kdo->vek;

    cout << "Zadejte vahu cloveka: " << endl;
    cin >> kdo->vaha;

    cout << "Zadejte jmeno cloveka: " << endl;
    cin.ignore();
    gets_s(kdo->jmeno); // Tato funkce nam nacte retezec ze standardniho vstupu
    kdo->dalsi = nullptr;
}


Clovek* prvniPrvek = nullptr;


void main()
{
    for (int i=0;i<2;i++) 
    {
        Clovek* novy = new Clovek;
        nactiCloveka(novy);
        
        if (prvniPrvek == nullptr)
        {
            prvniPrvek = novy;
        }
        else 
        {
            vlozDoSeznamu(prvniPrvek,novy);
        }

        cout << "Clovek byl vlozen do seznamu." << endl;
    }

    cout << endl;
    cout << "Vypisuji seznam:" << endl;

    // Vsichni jsou uz jiz nacteni, vypis cely seznam
    vypisCelySeznam(*prvniPrvek);

    // Koncime praci s programem, takze smazeme seznam
    smazCelySeznam(prvniPrvek);

    int c;
    cin >> c;

    smazCelySeznam(prvniPrvek);

}

Nahlásit jako SPAM
IP: 94.113.68.–
27. 1. 2015   #2
-
0
-

Ke strukturám by bylo vhodné přistupovat pomocí ukazatele. K položce struktury se pak dostaneš přes -> , takže  ukazatel->polozka .
Jméno je céčkovský řetězec. Je to pole typu char. Jméno tedy můžeš interpretovat jako pole znaků. Abys vybral jména začínající znakem A, stačí projít všechny "člověky" a porovnat první znak jména, asi takto: 

if (Clovek->jmeno[0] == 'A')  {
  //jmeno zacina na A
}

na BMI jsi najdi vzoreček, tuším, že se počítal z hmotnosti, výšky a věku.
U posledního prvku si nastav ukazatel dalsi na NULL, tak snadno najdeš poslední prvek - projdeš seznamem dokud nenarazíš na prvek s ukazatelem dalsi == NULL. Pak vypíšeš, nebo uděláš co je požadováno s tímto prvkem.

Pro práci se seznamem bych asi volil rekurzívní volání funkcí.

Edit: malá drobnost: pro vkládání kódu slouží tlačítko <?, usnadní to ostatním uživatelům fóra orientaci ve vloženém kódu.

hu

Nahlásit jako SPAM
IP: 2001:67c:1222:800:4cf5:1e...–
27. 1. 2015   #3
-
0
-

C++ ti umožňuje ještě trochu jiný přístup. Prvek seznamu vytvořit jako class s parametrickým konstruktorem, který umožní objektu nastavit počáteční hodnoty - výška váha, věk, jméno. Pro jméno bych použil std::string. Dále by měla třída metody GetBMI, IsLast (vrátí true pokud je to poslední položka seznamu) a NameBeginAtA (vrátí true pokud jméno začíná na A). 

hu

Nahlásit jako SPAM
IP: 195.178.67.–
haha0
Newbie
28. 1. 2015   #4
-
0
-

To s tím vyhledáním jména na A mi nejde. Podtrhává mi to Clovek->

Nevíte co s tím?

Nahlásit jako SPAM
IP: 94.113.68.–
KIIV
~ Moderátor
+43
God of flame
28. 1. 2015   #5
-
0
-

#4 haha
nepouzivat tam datovy typ, ale promennou  (Clovek je datovy typ a nejde nad nim volat ->)

Nahlásit jako SPAM
IP: 93.91.152.–
Program vždy dělá to co naprogramujete, ne to co chcete...
haha0
Newbie
28. 1. 2015   #6
-
0
-

Takže jak to má prosím vypadat?

Nahlásit jako SPAM
IP: 94.113.68.–
KIIV
~ Moderátor
+43
God of flame
28. 1. 2015   #7
-
0
-

zkopirujes si ukazatel z prvni prvek do nejakyho pomocnyho, otestujes, jestli to neni nullptr, zkontrolujes prvni pismeno, posunes se v seznamu na dalsi prvek a opakovani od kontroly na nullptr

Nahlásit jako SPAM
IP: 93.91.152.–
Program vždy dělá to co naprogramujete, ne to co chcete...
haha0
Newbie
28. 1. 2015   #8
-
0
-

Můžeš mi to prosím vysvětlit trošku lehčeji? (Jako pro blbečka:D)

Nahlásit jako SPAM
IP: 94.113.68.–
28. 1. 2015   #9
-
0
-

   

typedef struct {  //struktura jako datovy typ
int vek;
float hmotnost;
char jmeno[50];
} Clovek;

Clovek* nekdo;  //ukazatel na strukturu

//pred pouzitim musis ukazatel inicializovat, napr na prvni prvek seznamu

if (nekdo->jmeno[0] == 'A')  {
//jmeno zacina na A
}

hu

Nahlásit jako SPAM
IP: 193.86.81.–
haha0
Newbie
28. 1. 2015   #10
-
0
-

Napíšu to tak, ale tady:

if (nekdo->jmeno[0] == 'A')  {
//jmeno zacina na A
}

mi to u té šipky háže chybu a nevím, co s tím. 

Nahlásit jako SPAM
IP: 94.113.68.–
28. 1. 2015   #11
-
0
-
Nahlásit jako SPAM
IP: 193.86.81.–
q
~ Anonymní uživatel
219 příspěvků
28. 1. 2015   #12
-
0
-

Jak můžeš napsat tolik kódu a po každých pár řádcích všechno dělat úplně jinak, než těch pár řádků předtím?

Začni tím, že všechny proměnné a parametry typu Clovek přepíšeš na Clovek*.

Nahlásit jako SPAM
IP: 213.211.51.–
haha0
Newbie
28. 1. 2015   #13
-
0
-

Ani nevím, tohle jsme dělali se cvičícím na cviku, mám to podle něj.#12 q

Nahlásit jako SPAM
IP: 94.113.68.–
q
~ Anonymní uživatel
219 příspěvků
28. 1. 2015   #14
-
0
-

#13 haha
To je možné, ale když to všechno sjednotíš, tak nebudeš muset řešit, kde co dělat jinak, protože to budeš mít všude stejně. Časem se v tom zorientuješ, ale teď si to jen komplikuješ.

Nahlásit jako SPAM
IP: 213.211.51.–
ondrej39+1
Věrný člen
28. 1. 2015   #15
-
0
-

A když celej seznam zaobalíš do struktury nebo třídy, v níž budeš evidovat pointer na prvního člověka a aktuální počet prvků (který se bude měnit při přidání / odebrání do/ze seznamu), tak daným funkcím ani nemusíš předávat parametry pro seznam co upravuješ a budeš je volat nad danou strukturou. A navíc bude pěkně vidět, co kam patří. Dvě mouchy jednou ranou.

Nahlásit jako SPAM
IP: 213.226.234.–
Inject all the dependencies!
haha0
Newbie
28. 1. 2015   #16
-
0
-

#15 ondrej39
Jak to myslíš, prosímtě?

Nahlásit jako SPAM
IP: 94.113.68.–
ondrej39+1
Věrný člen
28. 1. 2015   #17
-
0
-

#16 haha
 

struct SeznamLidi {
	Clovek * m_pHead;
	int m_pocetLidi = 0;

	// a sem všechny metody, kterými seznam upravuješ,
	// nebo které používáš k tisku
};
Nahlásit jako SPAM
IP: 213.226.234.–
Inject all the dependencies!
haha0
Newbie
28. 1. 2015   #18
-
0
-

#17 ondrej39
Takže když si to napíšu tak, jako ty, tak kam pak napíšu to, co potřebuju zjistit? 

Nahlásit jako SPAM
IP: 94.113.68.–
ondrej39+1
Věrný člen
28. 1. 2015   #19
-
0
-

#18 haha
Jak to myslíš, co potřebuješ zjistit?

Nahlásit jako SPAM
IP: 213.226.234.–
Inject all the dependencies!
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 70 hostů

Podobná vlákna

Spojový seznam — založil lubabe

Spojový seznam — založil Luckin

Spojový seznam — založil TarderOrtex

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý