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 12. 04. 2013 15:26 — Editoval Katsushiro (12. 04. 2013 15:27)

Katsushiro
Místo: Rožnov pod Radhoštěm
Příspěvky: 144
Škola: VŠB TUO - FEI
Pozice: student
Reputace:   
 

C++ OOP - implementace stacku pomocí pointerů

Tak jsem začal s OOP. Ze školy jsem to moc nepobral (styl - jste na vysoké, tady na cviku už si to jen zkusíte a nic se nevysvětlí...), tak to zkouším tady. Moje idea byla, udělat stack defacto jako seznam (bez pole mě nenapadá, jak jinak se "vrátit" k prvkům pod topem), ale mám problém - v metodě Push nemůžu přijít na to, jak předat adresu předchozího prvku tomu novému jako prev (objekt item se vytvoří vždy nově a mimo fci to s ním nějak odmítá manipulovat :D).

P.s.: Jaký je rozdíl mezi stack *identifikator a stack *identifikator = new stack (stack je název třídy)?

Tady je kód:

Code:

#include <iostream>

using namespace std;

class stack{
private:
    int num; //hodnota prvku
    stack *next; //dalsi prvek
    stack *prev; //predchozi prvek - nenapada me, jak to lip resit, tady pouzivam pro prirazeni na vrchol, pri odebirani prvku Popem
public:
    stack();
    void Push(int push_num, stack *top); //fce prebira jako parametr cislo, ktere se ma vlozit a nejvyssi prvek
    int Pop(stack *top); //fce vraci prvek z vrcholu zasobniku a zaroven ho odebira
    int Top(stack *top);
    bool IsEmpty(stack *top);
    ~stack();
};

/**
    @brief Konstruktor - inicializuje num a next na NULL
*/
stack::stack(){
    num = NULL;
    next = NULL;
    prev = NULL;
}

/**
    @brief Push - funkce vlozi novy prvek na vrchol zasobniku
    @param1 hodnota vkladaneho cisla
    @param2 vrchol zasobniku
*/
void stack::Push(int push_num, stack *top){    
    stack *item = new stack; //vytvorim novy objekt tridy stack


    item->num = push_num;

    if(top->num == NULL){
        *top = *item;
        top->next = NULL;
        item->prev = top;
    }else{
        top->next = item;
        *top = *top->next;
        top->next = NULL;
    }


}

int stack::Pop(stack *top){

    if(top->num == NULL){
        cout << "V zasobniku nejsou zadne prvky!" << endl;
        return NULL;
    }else{
        int ret_num; //vracene cislo
        ret_num = top->num;
        if(top->prev == NULL){
            top->num = 999;
        }else{
            *top = *top->prev;
        }
        return ret_num;
    }    
}

int stack::Top(stack *top){
    return top->num;
}

bool stack::IsEmpty(stack *top){
    if(top->num == NULL){
        return true;
    }
    return false;
}

stack::~stack(){
    cout << "Ahoj :-)" << endl;
}

int main(){
    stack zasobnik; //vytvorim objekt

    zasobnik.Push(5, &zasobnik);
    zasobnik.Push(6, &zasobnik);
    cout << zasobnik.Pop(&zasobnik) << endl;
    cout << zasobnik.Top(&zasobnik) << endl;
    cout << zasobnik.IsEmpty(&zasobnik) << endl;


    return 0;
}

Moc díky za odpovědi, sám jsem bezradný :-D Katsu

Offline

 

#2 12. 04. 2013 18:32 — Editoval RePRO (12. 04. 2013 19:27)

RePRO
Místo: Jihlava
Příspěvky: 363
Škola: AI VŠPJ (09-12, Bc.)
Pozice: programátor
Reputace:   11 
Web
 

Re: C++ OOP - implementace stacku pomocí pointerů

Zdravím
a ten zásobník (stack) musíš implementovat spojovým seznamem? Je to ideální přes SS, ale dá se to pro doplnění třeba implementovat i vektorem (ne polem). Zkus tento kód porovnat se svým a opravit si chyby. Asi nejčistší způsob jak naznačuji je ten, že se udělá výčet možných stavů spojového seznamu, pak struktura uzel (prezentuje jeden prvek v seznamu) a samostatnou třídu zásobník, nad kterou budeme mít Konstruktor, Desktruktor, Push, Pop a IsEmpty.

Code:

#include <cstdlib>
#include <iostream>

using namespace std;

// stavy seznamu (OK, vyčerpaná paměť, prázdný seznam):
enum TStackStatus 
{
     ssOK,
     ssMemoryFull,
     ssIsEmpty
};

// uzel seznamu:
struct MyNode
{
     int data;
     MyNode *pNext;
};

// třída zásobník:
class MyStack 
{
     protected:
           MyNode *pTop;
           virtual void Destroy();
     public:
           MyStack();
           virtual ~MyStack();
           virtual bool IsEmpty() const;
           virtual TStackStatus Push(int data);
           virtual TStackStatus Pop(int &data);
};
    
// konstruktor - inicializace zásobníku
MyStack::MyStack()
{
     pTop = NULL;
}

// destruktor - zavolá se Destroy
MyStack::~MyStack()
{
    Destroy();
}

void MyStack::Destroy()
{
     MyNode *p, *pNext;
     // uzel pro zrušení:
     p = pTop;
     // dokud nejsme na konci:    
     while (p != NULL) {
             // následující uzel:
             pNext = p->pNext;
             // zrušení
             delete p;
             // další uzel pro zrušení:
             p = pNext;
     }
     // seznam je prázdný
     pTop = NULL;
}

// test prázdného zásobníku:
bool MyStack::IsEmpty() const
{
     return pTop == NULL;
}

// vložení prvku na vrchol zásobníku:
TStackStatus MyStack::Push(int Data)
{
     MyNode *pNew;
     // vytvoří nový uzel pokud není vyčerpaná paměť
     if (pNew = new MyNode, pNew == NULL) return ssMemoryFull;
     // nastaví data:
     pNew->data = Data;
     // zařadí uzel do seznamu:
     pNew->pNext = pTop;
     // pNew je nyní na začátku seznamu:
     pTop = pNew;
     // vrátíme stav OK
     return ssOK;
}

// odebrání prvku z vrcholu zásobníku:
TStackStatus MyStack::Pop(int &data)
{
     MyNode *pRemove;
     // pokud je zásobník prázdný, nelze nic odebírat a vrátíme stav IS_EMPTY
     if (IsEmpty()) return ssIsEmpty;
     // kopie dat:
     data = pTop->data;
     // uložení adresy rušeného uzlu:
     pRemove = pTop;
     // překlenutí rušeného uzlu:
     pTop = pTop->pNext;
     // zrušení uzlu:
     delete pRemove;
     // vrátíme stav OK:
     return ssOK;
}

int main(int argc, char *argv[])
{
      // test...
      system("PAUSE");
      return EXIT_SUCCESS;
}

Jinak nerozumím úplně tomu, jak se ptáš na ten rozdíl.
Základní rozdíl je v typu deklarací. Dělíme ji na statickou a dynamickou. Statické se tvoří v zásobníku a dynamické na haldě.

Statická deklarace a následná inicializace:

Code:

stack s;
s.hodnota = 10;

Dynamická deklarace a následná inicializace:

Code:

stack *s;
s->hodnota = 10;

Srdcem trochu-programátor, duší rádoby-matematik a povoláním analytik-vývojář.

Offline

 

Zápatí

Powered by PunBB
© Copyright 2002–2005 Rickard Andersson