Matematické Fórum

Nevíte-li si rady s jakýmkoliv matematickým problémem, toto místo je pro vás jako dělané.

Nástěnka
22. 8. 2021 (L) Přecházíme zpět na doménu forum.matweb.cz!
04.11.2016 (Jel.) Čtete, prosím, před vložení dotazu, děkuji!
23.10.2013 (Jel.) Zkuste před zadáním dotazu použít některý z online-nástrojů, konzultovat použití můžete v sekci CAS.

Nejste přihlášen(a). Přihlásit

#1 31. 03. 2020 16:00

Tmitheadway
Zelenáč
Příspěvky: 16
Reputace:   
 

Lineární spojový seznam

Dobrý den. Mohl mi někdo poradit jak se dá tohle vyřešit. Předem děkuju


Jedna se lineární spojový seznam se zarážkou.
Prvek seznamu obsahuje klíč (int), hodnotu (string) a ukazatel na následující prvek seznamu.
Prvky jsou uspořádané vzestupně podle klíče.
Seznam obsahuje maximálně jeden prvek s daným klíčem.
Implementujte následující metody třídy UsporadanySeznam:
-konstruktor, destruktor
konstruktor inicializuje seznam, destruktor by měl smazat všechny prvky seznamu.
-void vlozPrvek(int klic, const string& hodnota)
Vloží prvek do seznamu na správné místo podle klíče (pokud už prvek s daným klíčem v seznamu je, jen změní jeho hodnotu na novou).
-Prvek* najdiPrvek(int klic);
Zamyslete se nad efektivnějším algoritmem než známe pro běžný spojový seznam. Využijte toho, že prvky jsou seřazené podle klíče, není třeba procházet celý seznam.
-void smazPrvek(int klic);
Opět lze využít toho, že prvky jsou seřazené podle klíče, není třeba procházet celý seznam.
-void vypis();
Vypíše prvky seznamu jeden po druhém na konzoli (na jeden řádek). Např. ve tvaru: (2,"skrin") (8,"zidle") (10,"stul")
Možná bude potřeba implementovat i nějaké metody třídy Prvek (např. konstruktor(y))
Rozšířte přiložené testovací příklady pro metody: vlozPrvek, najdiPrvek a smazPrvek, aby co nejlépe pokryly možné situace.

už mam hotovou část, ale nejde tohle přeložit kvůli chybám. Možna někdo napoví jak s tím


#include "UsporadanySeznam.h"

UsporadanySeznam::UsporadanySeznam()
{
    prvni = new Prvek();
    zarazka = prvni;
}

UsporadanySeznam::~UsporadanySeznam()
{
    Prvek* P;
    P = prvni;
    while (prvni != zarazka)
    {
        P = prvni;
        prvni*= prvni->
        delete p;
    }
}

Prvek* UsporadanySeznam::najdiPrvek(int klic)
{
    Prvek* p = prvni;
    while (p != zarazka && klic < p->klic)
    {
        p = p->dalsi;
        if (p != zarazka && klic == p ->klic)
            return p;
            return nullptr;
    }
}

void UsporadanySeznam::vlozPrvek(int klic, const std::string& hodnota)
{
    Prvek* p =prvni;
    if ( prvni -> klic > klic || prvni == zarazka)
        {
            Prvek* n = new Prvek();
            n -> klic = klic;
            n -> hodnota = hodnota;
            n -> dalsi = prvni;
            prvni = n;
            return;
        }
}
void UsporadanySeznam::smazPrvek(int klic)
        {
            Prvek* p = prvni;
            if (p != zarazka && klic == p ->klic)
                delete p;
        }

void UsporadanySeznam::vypis()
{
    Prvek* p=prvni;
    while (p != zarazka)
    {
        cout<<"("<<p* klic<<"," <<p* hodnota <<",";
        p = p* dalsi;
    }
}
   

1) vloz, smaz- hotová je jen část (přidání prvního prvku, smazání prvku) , netuším jak s ostatními prvky
2) destruktor, vypis - myslím,že jsou tam syntaktické chyby, ale nevidím kde jsou
3) najdi - asi problém s těmi zavorkami nebo možna ještě něco chybí, nefunguje
4) prosím pomozte s konstruktorem Prvku a rozšířenými testy

Offline

 

#2 31. 03. 2020 16:30

LukasM
Příspěvky: 3274
Reputace:   193 
 

Re: Lineární spojový seznam

↑ Tmitheadway:
Za prvé by ses měl obtěžovat a poskytnout kompletní kód, tedy včetně obsahu headeru UsporadanySeznam.h.
Za druhé by bylo fajn, aby sis nejdřív opravil chyby, které zachytí kompilátor.  Např.

Code:

prvni*= prvni->
delete p;

asi tak úplně kompilátorem neprojde. Je tam celá řada chyb na pouhých dvou řádcích a kompilátor ti řekne, jaké to jsou. Kvůli tomu není třeba chodit sem.


Ve funkci najdiPrvek se zase vždy vrátí  hned v první iteraci cyklu a podobných problémů tam bude asi víc, ale jak říkám, nechce se mi to procházet, když jsi ani nedodal definici třídy Prvek.

Offline

 

#3 31. 03. 2020 16:41

Tmitheadway
Zelenáč
Příspěvky: 16
Reputace:   
 

Re: Lineární spojový seznam

↑ LukasM:↑ LukasM:

je to tady

#ifndef UsporadanySeznam_h
#define UsporadanySeznam_h


#endif /* UsporadanySeznam_h */
#pragma once
#include<string>

/* Jeden prvek seznamu. */
struct Prvek
{
    int klic=0;             // identifikator
    std::string hodnota=""; // nejaka hodnota (libovolny text)
    Prvek *dalsi=nullptr;   // ukazatel na dalsi prvek (naslednika)
   
    /* sem muzete pridat konstruktor(y) nebo dalsi metody */
};

/* Seznam Prvku usporadanych vzestupne podle klice.  */
class UsporadanySeznam
{
    Prvek *prvni;   // prvnн prvek seznamu nebo zarazka;
    Prvek *zarazka; // posledni specialni prvek seznamu;
   
    /*  void push_front(T data);
        void pop_back();
        void insert(T value, int index);
        void removeAt(int index);
    */
   
public:
    UsporadanySeznam();  // konstruktor
    ~UsporadanySeznam(); // destruktor
   
   
    Prvek* najdiPrvek(int klic);
    void vlozPrvek(int klic, const std::string& hodnota);
    void smazPrvek(int klic);
   
    void vypis();
   
    /* sem muzete pridat dalsi verejne metody */
   
};

Offline

 

#4 31. 03. 2020 16:43

Tmitheadway
Zelenáč
Příspěvky: 16
Reputace:   
 

Re: Lineární spojový seznam

↑ LukasM:

je ješte tu main

#include <iostream>
#include "UsporadanySeznam.h"
using namespace std;

/*Ukazka testovaci funkce pro metodu najdiPrvek() */
void vypisPrvek(UsporadanySeznam &t, int klic)
{
    Prvek* p = t.najdiPrvek(klic);
    if (p)
    {
        cout << "Nalezen prvek: ";
        cout << "(" << p->klic << "," << p->hodnota << ") ";
        cout << endl;
    }
    else
        cout << "Prvek " << klic << " nenalezen. \n";
}

void test()
{
    UsporadanySeznam t;
   
    /* Vkladani prvku: */
    t.vlozPrvek(9, "pracovni stul");
    t.vlozPrvek(3, "kancelarska zidle");
    t.vlozPrvek(6, "PC");
    t.vlozPrvek(6, "notebook");
    t.vlozPrvek(12, "lampa");
   
    t.vypis();
   
    /* Nalezeni prvku: */
    Prvek* p = t.najdiPrvek(9);
    if (p)
        cout << "Prvek 9 nalezen.\n";
    else
        cout << "Prvek 9 nenalezen.\n";
    vypisPrvek(t, 9);
    vypisPrvek(t, 1);
   
    /* Smazani prvku: */
    t.smazPrvek(10);
    t.smazPrvek(12);
    t.smazPrvek(6);
    t.smazPrvek(3);
    t.smazPrvek(9);
    t.smazPrvek(3);
   
    t.vypis();
}

int main()
{
    test();
    return 0;
}

Offline

 

#5 31. 03. 2020 16:56 — Editoval LukasM (31. 03. 2020 16:58)

LukasM
Příspěvky: 3274
Reputace:   193 
 

Re: Lineární spojový seznam

↑ Tmitheadway:
Pár poznámek:

1. Nikde nevidím funkci main, takže pokud to nekompiluješ jako knihovnu, tak to linkeru bude vadit. A těžko to bez ní otestuješ. (Edit: ano, po třetím příspěvku už je tu snad všechno.)

2. Když už OOP, tak pořádně. Minimálně metody vypis a najdiPrvek by měly být const.

3. Include guard v tom headeru je použitý úplně špatně. Pokud to má být k něčemu, je třeba přesunout ten #endif na úplný konec souboru. Pak je také možné vyhodit #pragma once, což dělá to samé (akorát je to non-standard). Ve tvém kódu je to samozřejmě jedno.


Znovu opakuji: oprav chyby, které odhalí kompilátor. Na řádcích, které jsem býše napsal je například toto:
1. první* nic neznamená. Asi chceš posunout ukazatel na další prvek, takže ta hvězdička tam nemá co dělat.
2. první-> evidentně postrádá identifikátor nějaké member proměnné.
3. p není deklarované. Názvy proměnných jsou case-sensitive.

Opravdu nevím, proč by chyby tohoto typu měl hledat někdo tady. I tak tam bude hodně logických chyb.

Offline

 

Zápatí

Powered by PunBB
© Copyright 2002–2005 Rickard Andersson