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

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:
#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
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.
#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:
stack s; s.hodnota = 10;
Dynamická deklarace a následná inicializace:
stack *s; s->hodnota = 10;
Offline