Elemente verkehrt auf Queue geschoben



  • Hi ich hab ein Programm geschrieben wo Int-Werte aus einer Datei auf ein Queue geschoben werden und danach per Bucketsort wieder sortiert in eine neue Datei ausgibt.Aber mein Programm schiebt die Elemente Verkehrt auf den Queue.

    #include <iostream>
    #include <fstream>
    
    using namespace std;
    
    #ifndef _QUEUE_H
    #define _QUEUE_H
    
    template <class T>
    class Queue
    {
    public:
    	Queue(): counter(0), topp (0){}		//Konstruktor
    	~Queue(){}				//Destruktor
    
    //Funktionsprototypen
    
    	void deque();		//löschen des ersten Elements
    	bool enque(const T&);	//einfügen eines Elements ans Ende
    
    	T& first()const;		//Zugriff auf das erste Element
    	bool isEmpty()const;		//Test ob Queue leer ist
    
    private:
    			class qNode
    				{
    				public:
    				T data;
    				qNode *next_element;
    				};	
    
    			qNode *topp;		//Zeiger auf erstes Element
    			int counter;		//zählt wie viel elemente in Queue
    
    };
    
    //Funktionen
    
    //prüft ob Queue leer ist, 0 Queue ist nicht leer und 1 Queue ist leer
    template <class T> bool Queue<T>::isEmpty()const
    	{
    	if(counter == 0)
    	return true;
    	else
    	return false;
    	}	
    
    //fügt Element am Ende an
    template <class T> bool Queue<T>::enque(const T& einzufuegendes_element)
    {
    	qNode *node = new qNode;
    	node->data = einzufuegendes_element;
    	node->next_element = topp;
    	topp = node;
    	++counter;
    	return true;
    }
    
    //löscht erstes element
    template <class T> void Queue<T>::deque()
    {
    	qNode *old_element = topp;
    	topp = topp->next_element;
    	delete old_element;
    	--counter;
    }
    
    //gibt erstes element zurück
    template <class T> T& Queue<T>::first()const
    {
    	return topp->data;
    }
    
    #endif
    
    int main(int argc, char *argv[])
    {
    	char *input;
    	char *output;
    	char in[10]="input.txt";
    	char out[11]="output.txt";
    
    	if(argc >= 3)
    		{
    			input = argv[1];
    			output = argv[2];
    		}
    	else
    		{
    			input = in;
    			output = out;
    		}
    
    	fstream quelle;
    	quelle.open(input, ios::in);
    
    	fstream ziel(output, ios::out);
    
    	Queue<int> intQueue;
    	cout << "Queue leer? 0->nein....1->ja    " << intQueue.isEmpty() << endl;
    
    	//Werte aus Datei auf Queue schieben
    
    	int value;
    	while(quelle >> value)
    		{
    			intQueue.enque(value);
    			cout << value << "  " << "abgelegt !" << endl;
    		}	
    
    	cout << "Queue leer? 0->nein....1->ja    " << intQueue.isEmpty() << endl;
    	cout << intQueue.first();
    
    	//bucketsort
    
    	//geöffnete Datein schließen
    	quelle.close();
    	ziel.close();
    }
    

    Gruß



  • Ähm, was ist mit deinem anderen Thread?
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-243507.html

    Abgesehen davon findest du sowas sehr schnell raus, indem du dir auf Blatt Papier kurz überlegst, wie deine Queue technisch ablaufen sollte, und dann über den Debugger mit deinem Programm vergleichst.



  • Schon ok, war en irrtum. Ist schon alles gelöst....
    😃



  • WINFO2105 schrieb:

    #include <iostream>
    #include <fstream>
    
    using namespace std;  //! Nicht in Headern!
    
    #ifndef _QUEUE_H //_X (Unterstrich, Großbuchstabe)-Bezeichner sind für Compiler reserviert - also nimm mal den Unterstrich am Anfang weg und benenn das makro mal iwie so, dass es definitiv niemand anders schon zufällig nutzt...
    #define _QUEUE_H
    
    template <class T>
    class Queue
    {
    public:
    	Queue(): counter(0), topp (0){}		//Konstruktor
    //	~Queue(){}				//Destruktor
    //einen leeren destruktor musst du auch nicht zu deklarieren+definieren - da reicht der compilergenerierte
    //Funktionsprototypen
    
    	void deque();		//löschen des ersten Elements
    	bool enque(const T&);	//einfügen eines Elements ans Ende
    
    //	T& first()const;		//Zugriff auf das erste Element
    //eine non-const referenz auf das erste element -> möglichkeit, daten zu ändern -> non-const memberfkt! also brauchen wir 2 fkt., wenn wir auch eine non-const reference wiedergeben wollen:
    	const T& first()const;		//Zugriff auf das erste Element
    	T& first();		//Zugriff auf das erste Element
    
    	bool isEmpty() const;		//Test ob Queue leer ist
    private:
    			class qNode
    			{
    			public:
    				T data;
    				qNode *next_element;
    //ein konstruktor ist nie falsch:
    				qNode(const T& value, qNode *_next_element)
    				: data(value), next_element(_next_element) //initialisierungsliste
    				{}
    			};	
    	
    			qNode *topp;		//Zeiger auf erstes Element
    			int counter;		//zählt wie viel elemente in Queue
    //den counter brauchst du eigtl nicht:
    size_t size() const
    {
     size_t R(0);
     for(qNode* i=topp; topp; topp = topp->next_element, ++R);
     return R;
    }
    	
    };
    
    //Funktionen
    
     
    //prüft ob Queue leer ist, 0 Queue ist nicht leer und 1 Queue ist leer
    template <class T> bool Queue<T>::isEmpty()const
    {
      return counter == 0;
    //bzw.
      return !counter;
    //oder ohne counter:
      return topp == 0;
    //also
      return !topp;
    }
    
    //fügt Element am Ende an
    template <class T>
    //bool - wieso bool, wenn du so und so immer true zurückgibst?
    void
    Queue<T>::enque(const T& einzufuegendes_element)
    {
    //	qNode *node = new qNode;
    //	node->data = einzufuegendes_element;
    //	node->next_element = topp;
    //	topp = node;
    
    //zwischenschritt, da wir jetzt einen konstruktor haben:
    //	qNode *node = new qNode(einzufuegendes_element, topp);
    //	topp = node;
    
    //wird zu:
    	topp = new qNode(einzufuegendes_element, topp);
    //und das hier bleibt, falls du weiter mit dem counter arbeiten möchtest:
    	++counter;
    }
    
    //löscht erstes element
    template <class T>
    void Queue<T>::deque()
    {
    	qNode *old_element = topp;
    	topp = topp->next_element;
    	delete old_element;
    	--counter;
    }
    
    //gibt erstes element zurück
    template <class T>
    const T& Queue<T>::first() const
    {
    	return topp->data;
    }
    
    //gibt veränderbares erstes element zurück
    template <class T>
    T& Queue<T>::first()
    {
    	return topp->data;
    }
    
    #endif
    
    #include <string>
    
    int main(int argc, char *argv[])
    {
    //	char *input;
    //	char *output;
    	const char in[]="input.txt"; //!
    	const char out[]="output.txt"; //!
    
    	if(argc >= 3)
    	{
    		input = argv[1];
    		output = argv[2];
    	}
    	else
    	{
    		input = in;
    		output = out;
    	}
    	
    	fstream quelle;
    	quelle.open(input, ios::in);
    	
    	fstream ziel(output, ios::out);
    	
    	
    	Queue<int> intQueue;
    //sieht so schöner aus, meinst du nicht auch?!
    	cout << "Die Queue ist ";
    	if (intQueue.isEmpty())
    		cout << "nicht ";
    	cout << "leer?" << endl;
    	
    	//Werte aus Datei auf Queue schieben
    	
    	int value;
    	while(quelle >> value)
    	{
    		intQueue.enque(value);
    		cout << value << "  " << "abgelegt !" << endl;
    	}	
    		
    
    //und so geht es kürzer:
    	cout << "Die Queue ist " << (intQueue.isEmpty() ? "nicht ");
    	cout << "leer?" << endl;
    
    	if(! intQueue.isEmpty()) //wichtig! ansonsten bekommst du hier müll!
    		cout << intQueue.first();
    
    	
    	/*...*/
    	
    //brauchst du nicht, weil die klassen das im destruktor automatisch machen:
    	//geöffnete Datein schließen
    //	quelle.close();
    //	ziel.close();
    }
    

    ich hoffe, es hilft dir...

    da es mir noch einfällt:
    du brauchst nen destruktor - allerdings musst du dort auch den speicherplatz freigeben - das macht man in der regel so:

    template <typename T>
    void clear() //zusätzliche öffentliche member-fkt, da man diese funktionalität ja auch nach außen anbieten kann
    {
      while(! isEmpty())
         deque();
    }
    
    template <typename T>
    Queue::~Queue() //unser destruktor ruft jz einfach clear auf...
    {
      clear();
    }
    

    bb

    gibt nat. noch ca. 100 andere kleine dinge, die man verbessern könnte - aber das sollte für den anfang erst mal genügen...



  • Ich würde zum Beispiel andere Bezeichner verwenden. deque ist schon mal sehr irreführend, da es in der Standardbibliothek einen Container mit diesem Namen gibt. Das steht dort für Double Ended Queue. Und enque ist nicht viel besser.

    Halte dich doch ein wenig an inoffizielle Konventionen und nenne die Methoden push und pop , dann weiss jeder, was gemeint ist. Oder hänge bei deinen Namen mindestens noch ein ue an, damit diese auch Wörter sind.


Anmelden zum Antworten