[gelöst] 3 ints sortieren ohne Werkzeug



  • Hallo Forianer,

    in meinem Lehrbuch ist folgende Aufgabe zu finden:

    Schreiben Sie ein Programm, das den Benutzer auffordert, drei Integer-Werte einzugeben, und dann die Werte in numerischer Reihenfolge getrennt durch Komma ausgibt. Wenn der Benutzer die Werte 10 4 6 eingibt, sollte die Ausgabe "4, 6, 10" lauten. Wenn zwei Werte gleich sind, sollten sie zusammenstehen; d.h., die Eingabe 4 5 4 sollte "4, 4, 5" ergeben.

    Nun habe ich mich eine ganze zeitlang mit Java beschäftigt, und auch in C++ hatte ich in der Vergangenheit schon zwei Anläufe, die Sprache zu lernen. Die Aufgabe ist also für mich nicht wirklich eine Schwierigkeit.

    Aber! Zu dem Zeitpunkt, zu dem die Aufgabe im Buch kommt, wurden die logischen Operatoren noch nicht besprochen, und auch die if-Verzweigung nicht wirklich, d.h., es wurde bisher nur ein ganz einfaches if benutzt, ohne Blockanweisung, ohne else, ohne alles.

    Meine erste Idee war, eine Hilfsvariable min zu definieren und die Zahlen darüber zu sortieren. Das hat aber ohne else-Zweig und ohne Anweisungsblock nicht funktioniert.

    Meine zweite Idee war, drei Hilfsvariablen min, med und max zu definieren, und in einer endlosen Folge von if-Abfragen die Zahlen darin zu sortieren. Ging aber im Endeffekt auch nicht auf.

    Zwar ist die Aufgabe jetzt nicht zwingend zum Weiterlernen. Zumal mir ja schon Mittel und Wege bekannt sind, die Aufgabe zu lösen. Ich habe aber den Ehrgeiz, das Buch wirklich komplett durchzuarbeiten, und ich würde die Aufgabe gern mit den bis zu dieser Stelle bekannten Mitteln hinbekommen.

    Hat irgendwer eine Idee und kann mir einen kleinen Tipp geben? Aber bitte wirklich nur einen kleinen Tipp, ich will's selbst rauskriegen. 🙂



  • P.S.: Dass man if-Verzweigungen schachteln kann, wurde bis zu dieser Aufgabe auch noch nirgends erwähnt oder benutzt.



  • #include <iostream>
    
    int main(int argc, char** argv)
    {
    	std::cout << "Geben Sie 3 Zahlen ein!" << std::endl;
    	int a, b, c;
    	std::cin >> a >> b >> c;
    
    	if(a < b && b < c)
    		std::cout << a << ", " << b << ", " << c << std::endl;
    	if(...)
    		...
    
    	.
    	.
    	.
    }
    

    ups. 😛



  • Wie gesagt, keine logischen Operatoren! :p

    Aber ich hatte gerade noch eine Idee... wenn's funktioniert, poste ich es gleich.



  • Das Maximum und Minimum zweier Zahlen laesst sich auch ohne Vergleich bestimmen:

    max(a,b) = (a + b + abs(b-a)) / 2
    min(a,b) = (a + b - abs(b-a)) / 2
    

    Wahrscheinlich auch auf 3 Zahlen erweiterbar. Oder so:

    geg: a,b,c
    a := min(a,b)
    b := max(a,b)
    
    b := min(b,c)
    c := max(b,c)
    
    a := min(a,b)
    b := max(a,b)
    


  • min()/max() und abs() gibt es an dieser Stelle auch noch nicht (das wäre ja auch wirklich *zu* einfach, grins).


  • Mod

    Ich habe jetzt nicht alle Fälle getestet, sollte aber passen:

    #include <iostream>
    
    int main()
    {
      int a,b,c;
      std::cin>> a >> b >> c;
      int min1,min2,min3;
      int m,n;
    
      if (a<=b) {min1=a; m=1;}
      if (a>b) {min1=b; m=2;}
      if (c<=min1) {min1=c; m=4;}
    
      if (a>=b) {min3=a; n=8;}
      if (a<b) {min3=b; n=16;}
      if (c>=min3) {min3=c; n=32;}
    
      int z=m+n;
    
      if(z==9) min2=a; 
      if(z==17) min2=c;
      if(z==33) min2=b;
      if(z==10) min2=c;
      if(z==18) min2=b;
      if(z==34) min2=a;
      if(z==12) min2=b;
      if(z==20) min2=a;
      if(z==36) min2=c;
    
      std::cout<<min1<<' '<<min2<<' '<<min3<<std::endl;
    
    }
    

    edit: Falls noch keine Anweisungsblöcke bekannt sind, kann man nach dem gleichen Schema auch mit einzelnen Zuweisungen auskommen. Ist aber nochmal eine runde umständlicher.



  • dennis.cpp schrieb:

    min()/max() und abs() gibt es an dieser Stelle auch noch nicht (das wäre ja auch wirklich *zu* einfach, grins).

    Dann bin ich aber langsam wirklich gespannt wie die Lösung aussehen soll, wenn du nicht mal so etwas coden darfst:

    int max( int a, int b )
    {
    	return ( a + b + abs(b-a) ) / 2;
    }
    
    int min( int a, int b )
    {
    	return ( a + b - abs(b-a) ) / 2;
    }
    
    int main()
    {
    	cout << max( 12, max(6, 4) ) << endl;
    	cout << min( 12, min(6, 4) ) << endl;
    }
    


  • dennis.cpp schrieb:

    min()/max() und abs() gibt es an dieser Stelle auch noch nicht (das wäre ja auch wirklich *zu* einfach, grins).

    min/max habe ich gerade als Funktionen definiert. Ich brauche sie nicht. Du kannst jedes Vorkommen von min/max durch die entsprechende rechte Seite im Programm ersetzen. Und anstatt zu sagen, was du alles nicht zur Verfuegung hast, waere es fuer mich einfacher, wenn du sagst, was du zur Verfuegung hast. Nacher darf man kein + mehr benutzen ...

    @icarus2: Deine Loesung ist unvollstaendig, du gibst nur Minimum und Maximum aus.



  • @SeppJ - du benutzt leider auch Blockanweisungen bei den if-Konstrukten. 😞

    So langsam gebe ich echt auf. Bei allen Ideen, die ich bisher hatte, lief es darauf hinaus, dass ich zum Schluss zwei Vergleiche in einer if-Anweisung hätte ausführen müssen.

    Entweder habe ich in dem Kapitel des Buches irgendwas übersehen, oder die Aufgabe ist mit den bis dahin vorgestellten Mitteln wirklich nicht lösbar, und Stroustrup setzt voraus, dass man sich zusätzlich informiert.

    Mein letzter Lösungsansatz sah so aus (std_lib_facilities.h ist ein Hilfsheader, der mit dem Buch mitgeliefert wird, um am Anfang einige Dinge zu verstecken und zu vereinfachen):

    #include "std_lib_facilities.h"
    int main()
    {
        cout << '\n';
        cout << "Bitte geben Sie drei ganze Zahlen ein: ";
        int value1, value2, value3;
        cin >> value1 >> value2 >> value3;
    
        int min, max;
    
        // Decide which one of value1 and value2 is smaller:
        if (value1 < value2)
            min = value1;
        if (value1 == value2)
            min = value1;
        if (value2 < value1)
            min = value2;
    
        // Repeat the action to also set the bigger one, since each
        // if-statement is only allowed to fulfil one sub-statement:
        if (value1 < value2)
            max = value2;
        if (value1 == value2)
            max = value2;
        if (value2 < value1)
            max = value1;
    
        // Start creating the output by the result of the above decision.
        string first_output;
        if (min == value1)
            first_output = "" + value1 + ", " + value2;
        if (min == value2)
            first_output = "" + value2 + ", " + value1;
    
        // If value3 is smaller than min, the output is obvious:
        string final_output;
        if (value3 < min)
            final_output = "" + value3 + ", " + first_output;
    
        // The same goes for value3 being bigger than max:
        if (value3 > max)
            final_output = first_output + ", " + value3;
    }
    

    Damit habe ich das Problem, value3 irgendwie in die Mitte setzen zu können, aber auch nur umständlich nach hinten verschoben.

    @knivil - vorgestellt und benutzt wurden bisher nur die arithmetischen Operatoren, einfache if-Anweisungen mit genau einer Folgeanweisung, die Bibliotheksfunktion sqrt(), die einfachen Datentypen und string, die Vergleichsoperatoren, die Zuweisung und cin / cout. Ich kann mir gerade nicht mehr vorstellen, dass die Aufgabe damit lösbar sein soll...


  • Mod

    dennis.cpp schrieb:

    @SeppJ - du benutzt leider auch Blockanweisungen bei den if-Konstrukten. 😞

    😮 Auch nicht erlaubt? Was darf man dann überhaupt? Aber wie ich schon kommentierte, ist das auch keine Problem, wenn man es eine Runde umständlicher mag:

    int a,b,c;
      std::cin>> a >> b >> c;
      int min1,min2,min3;
      int m,n;
    
      if (a<=b)  m=1;
      if (a>b)  m=2;
      if (m==1) min1=a;
      if (m==2) min1=b;
      if (c<=min1) m=4;
      if (m==4) min1=c;
    
      if (a>=b) n=8;
      if (a<b) n=16;
      if (n==8) min3=a;
      if (n==16) min3=b;
      if (c>=min3) n=32;
      if (n==32) min3=c;
    
      int z=m+n;
    
      if(z==9) min2=a; 
      if(z==17) min2=c;
      if(z==33) min2=b;
      if(z==10) min2=c;
      if(z==18) min2=b;
      if(z==34) min2=a;
      if(z==12) min2=b;
      if(z==20) min2=a;
      if(z==36) min2=c;
    
      std::cout<<min1<<' '<<min2<<' '<<min3<<std::endl;
    


  • Saugut. Da wäre ich heute nicht mehr drauf gekommen. Und morgen wahrscheinlich auch nicht. Das muss ich morgen nochmal ganz in Ruhe durchgehen.

    Grandios!



  • knivil schrieb:

    @icarus2: Deine Loesung ist unvollstaendig, du gibst nur Minimum und Maximum aus.

    Ja, ist klar. Ich wollte ja ach nur zeigen wie man es implementieren könnte. Den Rest hätte er wahrscheinlich selber geschafft.



  • Wenn man abs nicht verwenden darf, kann man es sich auch schnell selbst definieren. Damit sind keine logischen Operatoren wie && oder || enthalten, if ohne else und Block ... meine Implementation erfuellt also alle Anforderungen?

    int abs(int a)
    {
      if (a < 0) return -1*a;
      return a;
    }
    


  • Welches Buch soll das denn sein? Und auf welcher Seite steht die Aufgabe?



  • Ich tippe auf das hier: Einführung in die Programmierung mit C++ | ISBN: 3868940057
    Stroustrup wurde schon genannt, std_lib_facilities.h haben wir hier auch schonmal diskutiert.

    Ich kann mir nicht vorstellen, dass die Lösung so aussehen soll wie von SeppJ. Stroustrup ist sehr pragmatisch und darauf bedacht, guten Stil zu lehren; intellektuelle Kunststückchen verlangt er sicher nicht.



  • @knivil - Stimmt, auch dir vielen Dank. Wie abs() zu implementieren wäre, hätte ich allerdings nicht gewusst - Mathe ist schon verdammt lange her. Grins.

    @Bashar - genau das, ja. Wie gesagt, ich bin nicht sicher, ob Stroustrup das auch wirklich so gemeint hat. Tatsache ist aber, dass alles, was ich jetzt mal ausgeschlossen habe, vor dieser Aufgabe im Buch wirklich nicht besprochen und auch nicht angewendet wird. Man sollte aber vielleicht noch erwähnen, dass jedes Kapitel einen dreiteiligen Übungsteil hat. Im ersten Teil wird einfach nur angewendet, was besprochen wurde. Im zweiten Teil gibt es Wiederholungsfragen zum Inhalt des Kapitels. Und im dritten Teil gibt es *wirkliche* Aufgaben, bei denen eigenes Rätseln und Nachdenken gefordert ist. Kleine Puzzles eben. Und die Aufgabe stammt aus diesem dritten Teil. Stroustrup selbst sagt, dass die Aufgaben des dritten Teils Rätsel sind, die man für das Verständnis des Buches nicht bearbeiten *muss*. Obligatorisch sind nur die ersten beiden Übungsteile. Kann also gut sein, dass er vielleicht gerade doch auf solche "intellektuellen Kunststücke" aus ist. Vielleicht kann ich in ein paar Kapiteln mehr dazu sagen, wenn ich die anderen Aufgaben gesehen habe.



  • Vielleicht gibt es zu den aufgaben auch Loesungen des Autors.



  • knivil schrieb:

    Vielleicht gibt es zu den aufgaben auch Loesungen des Autors.

    http://www.stroustrup.com/Programming/Solutions/Ch3.html



  • Hm. Er benutzt logische Operatoren in seiner Lösung. Da muss ich nachher die ersten drei Kapitel nochmal durchblättern, ob ich das irgendwo übersehen habe. Falls nicht, schreibe ich ihm. 🙂



  • Hab das Buch nicht, aber nach dem Link von oben ist Kapitel 3.4 'Operationen und Operatoren'. Da wird das wohl drin stehen.
    Insgesamt einer der überflüssigsten Threads, die ich hier je gesehen habe 😉


Anmelden zum Antworten