Taschenrechner als Kellerautomat



  • huwul schrieb:

    Zweiteres verstehe ich nicht ganz. Ich lese doch eine Zeichenkette ein, mit der solange gerechnet wird, bis Ihre Länge 0 entspricht bzw die Größe des Stacks dann.

    (Hab meinen Beitrag oben nochmal minimal editiert)

    Geh mal das Beispiel aus der Aufgabenstellung anhand Deines Codes durch. Noch bevor die 8 auf den Stack pushed (Z. 37), rufst Du

    int num1 = stack_.top();
                    stack_.pop();
                    int num2 = stack_.top();
    

    (Zeile 20-22) auf. Auf einem leeren Stack. Das kann nicht funktionieren! Der Teil des Codes darf nur dann aufgerufen werden, wenn das aktuelle Zeichen eins von +-*/ ist.



  • Okay soweit so gut, habe es jetzt in den Cases initialisiert.
    Sieht dann so aus:

    #include <iostream>
    #include <string>
    #include <stack>
    using namespace std;
    
    class Calculator {
    	private:
    		string expr_;
    		stack<int> stack_;
    
    	public:
    		string expr;
    		Calculator(const std::string& expr) : expr_(expr) {}
    		int compute() 						// Berechnung
    		{
    
    			for(int i = 0;i<expr.size();i++)
    			{
    				char c = expr[i];
    
    				switch(c)
    					{
    						case '+':{ 	int num1 = stack_.top();
    								stack_.pop();
    								int num2= stack_.top();
    								stack_.pop();
    								stack_.push(num2+num1);
    								break;}
    						case '-': {	int num1 = stack_.top();
    								stack_.pop();
    								int num2= stack_.top();
    								stack_.pop();
    								stack_.push(num2-num1);
    								break;}
    						case '/':{	int num1 = stack_.top();
    								stack_.pop();
    								int num2= stack_.top();
    								stack_.pop();
    								stack_.push(num2/num1);
    								break;}
    						case '*':{	int num1 = stack_.top();
    								stack_.pop();
    								int num2= stack_.top();
    								stack_.pop();
    								stack_.push(num2*num1);
    								break;}
    						case '1': stack_.push(1);
    								break;
    						case '2': stack_.push(2);
    								break;
    						case '3': stack_.push(3);
    								break;
    						case '4': stack_.push(4);
    								break;
    						case '5': stack_.push(5);
    								break;
    						case '6': stack_.push(6);
    								break;
    						case '7': stack_.push(7);
    								break;
    						case '8': stack_.push(8);
    								break;
    						case '9': stack_.push(9);
    								break;
    						case '0': stack_.push(0);
    								break;
    					}
    
    				//cout << " aktueller Kellerspeicher : " << stack_.top() << endl;
    			}
    			return stack_.top();
    
    		}
    };
    

    Leider erhalte ich damit allerdings immernoch Speicherzugriffsfehler.



  • Hallo

    Denn Fehler, denn du jetzt noch rein gebaut hast, ist wirklich ein Leichtsinns Fehler. In meiner Vorlage, hab ich dir schon eine Variable "expr_" eingebaut, die durch den Konstruktor auch richtig initialisiert wird.

    Du benutzt in deiner Berechnung aber eine neue Variable vom Namen "expr" (Z12 definiert, Z19+21 Zugriff). Was erst mal nicht schlimm ist, da die Schleife einfach nicht bearbeitet wird. Am Ende greifst du aber auf den Stack zu, auf dem ja kein Wert eingetragen wurde.

    Also Z12 entfernen und Z19+21 anpassen dann geht es.

    MfG mdn



  • Achja stimmt, da hat sich wohl ein Fehler eingeschlichen.

    Nun denn es funktioniert einwandfrei jetzt.

    Dankeschön schonmal für die super Hilfe!! 👍 👍

    Eine letzte Frage:

    Wenn man verlangt, dass nach jedem Durchlauf der Kellerspeicher ausgegeben werden soll, ist gemeint, dass die Zahl die im Stack quasi als erstes drinsteht ausgegeben werden soll oder die gesamten Zahlen?


  • Mod

    huwul schrieb:

    Wenn man verlangt, dass nach jedem Durchlauf der Kellerspeicher ausgegeben werden soll, ist gemeint, dass die Zahl die im Stack quasi als erstes drinsteht ausgegeben werden soll oder die gesamten Zahlen?

    Vermutlich alles. Es soll ja wohl der Kontrolle dienen, ob alles richtig gemacht wurde.



  • Habe das jetzt mal über Nacht bedacht, da ich später in der Übung Sitze wo ich das alles abgeben muss, um den Kellerspeicher komplett auszugeben bräuchte ich einen zweiten stack oder nicht?
    Sonst müsste ich doch per top und pop alles rauslesen lassen?
    Sry bin am Handy deshalb grade kein Code verfügbar



  • Ja um es komplett auszulesen brauchst du eine 2te Struktur, in der du die Daten zwischenspeicherst.

    Leiter unterstützt der Stack-Container keine iteratoren.

    MfG mdn



  • Als Lösung habe jetzt leider keinen code zur Verfügung wegen Handy, aber man kann den Stack ja quasi spiegelverkehrt in einem String speichern und in einer Schleife wieder ausgeben lassen.


  • Mod

    huwul schrieb:

    Als Lösung habe jetzt leider keinen code zur Verfügung wegen Handy, aber man kann den Stack ja quasi spiegelverkehrt in einem String speichern und in einer Schleife wieder ausgeben lassen.

    Mit dem obersten Element anzufangen macht doch am meisten Sinn?
    also im Prinzip

    void print_stack(stack<int> s) // by value
    {
        while (!s.empty())
        {
             ... // Ausgabe von s.top()
             s.pop();
        }
    }
    


  • Nicht direkt, hatte genau so eine whilw Schleife eingebaut aber sie gibt erst nur alle Werte raus und dann immer nur die Rechenoperation und nicht wenn zB Von unten drin steht 3 1 2 und 2+1 wird ausgeführt gibt ehe nur 3 aus und nicht 3 und 3.

    Deshalb das Speichern im Strinf


Anmelden zum Antworten