Taschenrechner



  • Hallo,

    ich schreibe zur Zeit einen Taschenrechner in C++. Die jetzigen Funktionen sind schonmal Addition, Subtraktion, Multiplikation und Division sowie die Regel Punktrechnung vor Strichrechnung. Bin grad dabei die "Klammer-Rechnung" in den Code einzufügen...

    Somit kann er folgendes rechnen
    3+6*8-4/7...

    Was ich nun wissen wollte ist, wisst ihr ein schönes Tutorial zu einenr Programmierung eines Taschenrechners und sagt bitte nicht das Bsp. aus den Buch von
    Bjarne Stroustrup;) Oder wie würdet ihr an die Sache ran gehen, so vom Grundprinzip?

    Vielen Dank
    MfG
    Stefan



  • Punkt 1: Grammatik erstellen



  • Guter Anfang:), blos wie kann ich die am besten "bemerken", sicher durch einen Parser. Aber weil ich noch ein Noob in C++ bin und auch keine Ahnung von Klassen oder so habe, musste ich für mein jetziges Programm doch ziemlich mit der Brechstange einen basteln, wenn man den überhaupt Parser nennen kann. Der sieht nämlich "ungefähr" so aus:

    double *Zahlen_Filter(double *Zahlen,string Eingabe)
    {
    	int length=Eingabe.length();
    	int Zahl,p=-1,i=0;
    	for(;Eingabe[i]!=';';)
    	{
    		p++;
    		Zahl=0;
    		if(Eingabe[i]>='0'&&Eingabe[i]<='9')
    		{
    			while(Eingabe[i]>='0'&&Eingabe[i]<='9')
    			{
    				Zahl=10*Zahl+Eingabe[i++]-'0';
    			}
    		}
    		else
    		{
    			Zahl=Eingabe[i];
    			i++;
    		}
    		Zahlen[p]=Zahl;
    	}
    	return Zahlen;
    }
    

    Gibt es noch was anderes was ich verstehen könnte, oder müsste ich mich erst mal auf ein anderes Gebiet von C++ stürzen um einen Parser schreiben zu können.

    Stefan



  • |-STORM-| schrieb:

    Oder wie würdet ihr an die Sache ran gehen, so vom Grundprinzip?

    Infix-Ausdruck in die Postfix-Schreibweise transformieren => Postfix-Ausdruck mit einem Stack parsen.



  • Was macht denn dein Zahlen_Filter? Komplett kontextfrei alle Zahlen in ein Array packen?

    Sowohl Push Down Automaton als auch Recursive Decent Parser wären geeignete Suchwörter für dich.

    Davor bietet es sich jedoch an dich noch ein wenig eingehender mit C++ zu beschäftigen, insbesondere auch mit der Standardbibliothek (Stichwort string->double) 😉



  • Hab mal im Netz nach den Begriffen gesucht und was gefunden, wer will kann hier http://www.leda-tutorial.org/de/inoffiziell/ch02s04s01.html .

    @finix
    Warum string->double? Wegen der Funktion mit *Zahlen_Filter



  • Hi,

    hab mal noch ne Frage an euch zu den stacks. In C++ ist ja die stack.h in der Standardbibliothek drin, aber wie verwende ich die? Kenn nicht einmal die Befehle und meine Suche im Netz blieb bis jetzt neben den gefunden erfolglos. Will das gefundene nicht nehmen, weil es eine Erweiterung zur Standardbibliothek ist, somit müsste man es auch ohne diese Erweiterung klappen.
    Wäre somit sehr erfreut wenn einer mal "kurz" erklärt wie ich Zahlen einfach Staple und dann darauf zugreife:)

    Danke
    MfG
    Stefan


  • Mod

    der Standard C++ header ist <stack> und nicht stack.h!!!
    stack ist kein container sondern ein adapter auf irgendeinen anderen container, der stackoperationen zulässt. verwendung etwa so:

    #include <iostream>
    #include <stack>
    
    // sinnfreies beispiel mit allen funktionen
    #include <stack>
    int main()
    {
        std::stack<int> s;
        s.push( 10 );
        s.pop();
        for( int i = 0; i < 10; ++i ) s.push( i );
        int x = s.size();       // == 10
        do
        {
            s.top() += x;
            x = s.top();
            s.pop();
        }
        while( !s.empty() );
        std::cout << x;         // == 55
        return 0;
    }
    


  • Danke:) für so ein schönes Bsp.
    Kann die Größe des stacks auch im Code noch nicht definiert sein? Sondern so vergrößert werden wie grad gebraucht wird? Beim meinen Ziel des TSR ist ja die Eingabenlänge nicht von Anfang an bestimmt.


  • Mod

    der stack wächst, solange speicher da ist, die 10 ergibt sich im beispiel dadurch, dass zuvor 10 elemente abgelegt wurden. anfangs ist der stack leer. ein s.size() dort würde also 0 liefern. empty() ist im grunde nichts anderes als size()==0.



  • Kann ich dann auch, z.B. bei der gestapelten Folge
    2 5 1 4 8 7
    folgendes machen 14=4
    2 5 4 8 7
    |
    | <--5
    (4+8)
    v
    2 60 7
    Also ein Element oder mehrere in den Stapel löschen und die anderen runter fallen lassen?


  • Mod

    du kannst immer nur auf das oberste elemnt zugreifen. andernfalls währe es kein stack mehr. du könntest dann genauso gut auch vector, list oder deque nehmen, die alle über ein push_back() etc. verfügen.



  • Hmm, ok.

    Nun hoff ich mal die letzte Frage;) nochmal zu den stack. Bei der umgekehrt polnischen Notation muss ich mir ja irgend wie die Operatoren merken, wie hier z.B.:
    3+4*2+4*(1+1)
    ist ja dann
    342*+411+*
    Doch wie kann ich da die Operatoren merken?
    Im Stack geht ja dann folgendes
    3 -> 3,+ -> 3,4,+ -> 3,4,2,* -> 3,8,+

    Da fehlt mir noch der zündende Gedanke, die Zahlen werden ja gestapelt, aber woher weis ich was für ein Operator z.B. nach der ersten Zahl kam, wenn nach der zweiten ein "Mal" kommt?



  • die ops müssen natürlich auch auf den stack.
    K.



  • Und wie würdeste die dann verwenden?
    Duch ein temporäres Zwischenspeichern einieger Werte, weil man doch nur auf den obersten Wert zugreifen kann, darum der Denkfehler bei mir, was wenn das stack die Form
    342*+ hat?


Anmelden zum Antworten