Stack Array



  • Moin!
    Ich stehe vor einem Problem und finde kein Anfang.
    Es handelt sich um ein Stack der mit einem Array realisiert werden soll.
    Da hier kein Template benutzt werden soll muss das Info Element ein Zeiger auf eine virtuelle Basisklasse sein. Ich bin nicht sicher ob es so oder auch anders gelöst werden kann.
    Vllt kann mir jemand bei dieser Fragestellung helfen:

    Bei einem Brettspiel werden Chips unterschiedlicher Art verwendet (hier: Chip_0, Chip_1
    und Chip_2). Die Spiellogik erfordert, dass diese Chips in einer gemeinsamen Stapel-Datenstruktur
    verwaltet werden.
    Zum Beispiel so:

    Stack st;
    
    try
    {
      while( true )
      {
        switch( getRandomNullBisZwei() ) // diese function sei gegeben
        {
        case 0:
          st.push( new Chip_0 );
          break;
        case 1:
          st.push( new Chip_1 );
          break;
        case 2:
          st.push( new Chip_2 );
          break;
        }
      }
    }
    catch( Stack:: StackIstVollException )
    {
    }
    
    st.zeigAnzahlChips();
    
    Ausgabe:
        Anzahl Chips vom Typ 0: 35
        Anzahl Chips vom Typ 1: 31
        Anzahl Chips vom Typ 2: 34
    

    - Definieren Sie alle erforderlichen Klassen vollständig, so dass obige Ausgabe erzeugt wird, allerdings sollen keine Templates eingesetzt werden.
    - Die maximale Anzahl Chips ist 100, daher soll für den Stapel eine Array-Konstruktion verwendet werden.
    - Die Methode zeigAnzahlChips() gibt die Anzahl der im Stapel befindlichen Chips separat für jede Chipart aus. Die Summe muss die Gesamtanzahl ergeben (siehe oben: der Stapel ist mit 35+31+34=100 Chips gefüllt).
    - pop(...) und getRandomNullBisZwei() sind nicht gefordert.

    So das ganze nochmal in schön editiert.
    Ich habs erstmal versucht mit meinem Wissen (Exceptions kommen morgen dran)

    #include <iostream>
    using namespace std;
    
    class Base
    {
    public:
    	int typ;
    	Base () {}
    	Base (int jojo)
    		: typ(jojo)
    	{}
    };
    
    class Chip_0 : public Base
    {
    public:
    	Chip_0()
    	{
    		Base(0);
    	}
    };
    
    class Chip_1 : public Base
    {
    public:
    	Chip_1()
    	{
    		Base(1);
    	}
    };
    
    class Chip_2 : public Base
    {
    public:
    	Chip_2()
    	{
    		Base(2);
    	}
    };
    
    class Stack
    {
    	struct node
    	{
    		Base info;
    		node* next;
    	};
    
    	node* head;
    	Stack feld;
    
    public:
    	Stack()
    	{
    		head = NULL;
    	}
    	~Stack()
    	{
    		node* hilf = new node;
    		while (head != NULL)
    		{
    			hilf = head;
    			head = head->next;
    			delete hilf;
    		}
    	}
    
    	void push(Base ding)
    	{
    		node* hilf = new node;
    
    		if (hilf = 0)
    		{
    			cout << "Error";
    			exit(1);
    		}
    
    		if (head = NULL) //In leere Liste einfügen
    		{
    			hilf->info = ding;
    			hilf->next = NULL;
    			head = hilf;
    		}
    		else //In bestehende liste einfügen
    		{
    			hilf->info = ding;
    			hilf->next = head->next;
    			head = hilf;
    		}
    	}
    
    	void zeigAnzahlChips()
    	{
    		int c0 = 0;
    		int c1 = 0;
    		int c2 = 0;
    		node* hilf = head;
    		while (hilf->next != NULL)
    		{
    			if (hilf->info.typ == 0)
    				c0++;
    			if (hilf->info.typ == 1)
    				c1++;
    			if (hilf->info.typ == 2)
    				c2++;
    			hilf = hilf->next;
    		}
    		cout << "Anzahl Chips vom Typ 0: " << c0 << endl;
    		cout << "Anzahl Chips vom Typ 1: " << c1 << endl;
    		cout << "Anzahl Chips vom Typ 2: " << c2 << endl;
    	}
    
    };
    


  • nun, als erstes solltest du die gedanken um die stack-klasse machen. du brauchst ein konstruktor, (falls ein dynamisches array verwendent wird, einen destruktor), eine push funktion und eine pop funktion.

    soetwas also

    class stack
    {
    public:
        stack();
        ~stack();
        void push(const Chip *) throw StackIstVoll;
        Chip *pop() throw StackIstLeer;
    private:
        Chip *Chips[100];
        unsigned int count;
    };
    

    sowie noch die beiden exeption klassen.



  • Zeiteisen schrieb:

    Vllt kann mir jemand bei dieser Fragestellung helfen:

    Wenn du deinen bisherigen Versuch zeigen würdes oder schreiben könntest WAS dir Probleme bereitet?

    Kleiner Tip: Unterschiedliche Chips würde ich als unterschiedliche Klassen definieren, und dank Polymorphie sollte sich damit auch erklären was im Array stehen soll (sofern man nicht masochistisch veranlagt und auf void* ausweichen will).

    Noch eine Bitte: Für C/C++ Code das entsprechende Tag (Tip: Über den entsprechenden Button unterhalb des Eingabebereiches) verwenden, und so einrücken das es für andere lesbar ist.



  • Und noch was: Wer solchen Code (auch in einer Aufgabenstellung) verwendet, gehört erschlagen. Wenn man Exceptions fängt muss auch eine Behandlung erfolgen (Und sei es das man wenigstens einen Fehler ausgibt).

    catch( Stack:: StackIstVollException )
    {}
    

    Von anderen Dingen mal Abgesehen (Wie die frage ob man wirklich eine Kopie der Exception anlegen muss, oder ob eine const Referenz nicht besser wäre).

    cu André
    P.S: Ist ja noch schlimmer. Wer zum Henker verwendet Exceptions um Schleifen zu beenden?





  • Funktioniert denn die Vererbung der Klasse Basis, dass die Konstruktoren von Chip_x den Konstruktor der Elternklasse aufruft? Wenn ich dann im Main schreibe

    Stack st
    st.push (new Chip_x)
    

    Ich vermute so läuft das nicht...



  • Zeiteisen schrieb:

    Funktioniert denn die Vererbung der Klasse Basis, dass die Konstruktoren von Chip_x den Konstruktor der Elternklasse aufruft? Wenn ich dann im Main schreibe

    Stack st
    st.push (new Chip_x)
    

    Ich vermute so läuft das nicht...

    Nach deiner Aufgabe werden die Speziellen Konstruktoren aufgerufen. Und das funktioniert.

    class ChipBase
    {
      public:
        virtual ~ChipBase() {};
        // ggf. noch weitere virtuelle Methoden
    };
    
    class Chip_0 : public ChipBase {};
    class Chip_1 : public ChipBase {};
    class Chip_2 : public ChipBase {};
    
    int main()
    {
      // ...
      Stack st;
      st.push(new Chip_0);
      st.push(new Chip_1);
      st.push(new Chip_2);
      // ...
    }
    


  • Hierbei erhalte ich folgende Fehlermeldung:

    d:\eigene dateien\visual studio 2005\projects\klausur ws07\aufgabe4\aufgabe4.cpp(6) : error C2664: 'Stack::push': Konvertierung des Parameters 1 von 'Chip_1 *' in 'Base' nicht möglich
    Quelltyp konnte von keinem Konstruktor angenommen werden, oder die Überladungsauflösung des Konstruktors ist mehrdeutig
    Das Buildprotokoll wurde unter "file://d:\Eigene Dateien\Visual Studio 2005\Projects\Klausur WS07\Aufgabe4\Debug\BuildLog.htm" gespeichert.

    st.push ( new Chip_1 );
    

    funktioniert nicht da push in der Class Stack:

    void push(Base ding)
    

    Bin grad etwas Ratlos wie das zu lösen ist.
    Allerdings ist die ganze Aufgabe anders zu lösen da ich kein Array verwende. Das wäre die nächste Frage... Wie ist der Array im Stack zu realisieren wie es in der Aufgabe gefordert wird.

    Tja mein Prof beendet anscheinend Schleifen mit Exceptions...

    und... FINALE!!!



  • Dingesn geht nur mit Pointern. Stack muss push(Base* ding) haben.



  • Zeiteisen schrieb:

    [...]
    class Stack
    {
        struct node
        {
            Base info;
            node* next;
        }; 
    [...]
    

    Ist das nicht eine einfach verkettete Liste?
    Ist ein Stack nicht etwas Anderes, oder kann man einen Stack
    auch als Liste modellieren?



  • für einen stack brauchst du im prinzip nur die funktionen back, push_back und pop_back - sehe kein hindernis, warum das nicht als liste implementiert werden könnte. sogar für std::stack kann der container eine std::list sein.


Anmelden zum Antworten