Sortieren Sie 3 Zahlen ohne Verwendung von logischen Operatoren.



  • Hallo Leute,
    könnt ihr mir sagen wo ich der Fehler habe? oder was ich besser machen sollte

    #include<iostream>
    using namespace std;
    
    int main(){
    
    	int a,b,c;
    	cout << "Bitte geben Sie die Zahle ein" << endl;
    	cin >> a >> b >> c;
    
    	if(a > b)
    		if(b > c)
    			cout << a << b << c <<" erste " << endl ;
    		else
    			cout << a << c << b <<" zweite "<< endl;
    
    	if(b > c)
    		if(c > a)
    			cout << b << c << a <<" dritte "<< endl;
    
    		else
    			 cout << b << a << c <<" vierte "<< endl;
    	if(c > b)
    		if(b > a)
    			cout << c << b << a << " fünfte "<< endl;
    		else 
    			cout << c << a << b << " sechste "<<endl;
    
    	return 0;
    }
    

    bei andere eingaben liefert richtige ausgabe aber bei diese eingaben folgende

    4
    1
    7
    471 zweite
    741 sechste

    7
    4
    1
    741 erste
    471 vierte

    7
    1
    4
    741 zweite
    471 sechste

    danke euch


  • Mod

    Wenn a > b ist, kann ja trotzdem auch c > b sein, d.h. du läufst sowohl in den Fall in Zeile 10 als auch in den Fall in Zeile 22 rein. Mal dir am besten mal ein Diagramm auf Papier mit allen möglichen Verzweigungen. Achte beim Programmieren auf das richtige Setzen der else . Bei komplizierten if-else Konstrukten, wie hier, empfiehlt es sich, ein paar Klammern zu setzen. Ein geübter Programmierer weiß zwar, welches if zu welchem else gehört, aber es macht die Sache wesentlich lesbarer und für ungeübte Programmierer (z.B. dich 😉 ) beseitigt es eine große Fehlerquelle.



  • Du nutzt doch logische Operatoren ( < ).

    Lass doch die Zahlen von std::sort sortieren...

    #include <iostream>
    #include <algorithm>
    #include <functional>
    #include <iterator>
    
    int main()
    {
        std::cout << "Bitte Zahlen eingeben!" << std::endl;
    
        int arr[3];
        std::cin >> arr[0] >> arr[1] >> arr[2];
    
        std::sort(arr, arr + 3, std::greater<int>());
    
        std::cout << "Sortiert: " << a[0] << ", " << a[1] << ", " << a[2];
    }
    

  • Mod

    Sone schrieb:

    Du nutzt doch logische Operatoren.

    Stell dich doch nicht doof. Du weißt genau, was er meint. Dahingegen ist deine Lösung garantiert nicht der Aufgabenstellung entsprechend und noch nicht einmal lehrreich und auch noch wesentlich umständlicher. 👎



  • Klar, bei Einsteigeraufgaben in Sachen Programmierung, wird man sich sicher freuen wenn std::sort verwendet wird. 🙄
    Dass hier keine Bibliotheksfunktionen genutzt werden sollen ist wohl klar.



  • danke euch
    hat sich erledigt, aber die Lösung ist vieleicht nicht gerade schön

    #include<iostream>
    using namespace std;
    
    int main(){
    
    	int a,b,c;
    	cout << "Bitte geben Sie die Zahle ein" << endl;
    	cin >> a >> b >> c;
    
    	if (a > b) {
    			if (a > c) {
    				if (b > c) {
    					cout << a << " > " << b << " > " << c << endl;
    					}
    				if (c > b) {
    					cout << a << " > " << c << " > " << b << endl;
    					}
    			}
    			if (c > a) {
    				cout << c << " > " << a << " > " << b << endl;
    				}
    		}
    
    		else if (b > a) {
    			if (b > c) {
    				if (a > c) {
    					cout << b << " > " << a << " > " << c << endl;
    					}
    				if (c > a) {
    					cout << b << " > " << c << " > " << a << endl;
    					}
    			}
    			if (c > b) {
    				cout << c << " > " << b << " > " << a << endl;
    				}
    		}
    
    		else if (c > a) {
    			if (c > b) {
    				if (a > b) {
    					cout << c << " > " << a << " > " << b << endl;
    					}
    				if (b > a) {
    					cout << c << " > " << b << " > " << a << endl;
    					}
    			}
    			if (b > c) {
    				cout << b << " > " << c << " > " << a << endl;
    				}
    		}
    
    	return 0;
    }
    

    @seppJ hast recht, ohne klammer wurde ich mich nicht auskennen

    lg khati



  • Ich stelle mich nicht doof! Was soll er denn sonst darunter meinen, da fällt mir echt nichts ein 😞

    Außerdem ist meine Lösung lehrreich und überhaupt nicht umständlicher (???) aber Hauptsache Sepp hat wieder 3 Argumente dagegen stehen.



  • Hmm, wie würdet ihr das lösen, ohne Vergleichsoperatoren zu benutzen? Ich würde es so machen:

    #include<iostream>
    using namespace std;
    
    int divide(int lhs, int rhs)
    {
    	return lhs/rhs;
    }
    
    int main()
    {
    	int a=7;
    	int b=11;
    	int c=12;
    
    	if( divide(a,b) && divide(a,c) )
    	{
    		if( divide(b,c) )
    			cout << a << ' ' << b << ' ' << c;
    		else
    			cout << a << ' ' << c << ' ' << b;
    	}
    	else if( divide(b,a) && divide(b,c) )
    	{
    		if( divide(a,c) )
    			cout << b << ' ' << a << ' ' << c;
    		else
    			cout << b << ' ' << c << ' ' << a;
    	}
    	else
    	{
    		if( divide(a,b) )
    			cout << c << ' ' << a << ' ' << b;
    		else
    			cout << c << ' ' << b << ' ' << a;
    	}
    }
    

    Komplett ohne logische Operatoren fällt mir grad nichts ein.


  • Mod

    Probier bei dir mal aus, was bei Gleichheit passiert. Jetzt, da du es hast, kann ich dir auch eine vereinfachte Lösung zeigen:

    (a > b)
     {
      (a > c)
       {
        (b > c)
          -> abc
         else
          -> acb
       }
       else
       {
         -> cab
       }
     }
    else
     {
      (b > c)
       {
        (c > a)
          -> bca
         else
          -> bac
       }
       else
       {
         -> cba
       }
     }
    

    Wie du siehst, kommt jede Möglichkeit nur noch einmal vor. Bei dir werden einige Arme nie angesprungen. (Hoffentlich habe ich mich nicht verhaspelt. Jedenfalls sollten sechs Arme reichen)

    Sone schrieb:

    Ich stelle mich nicht doof! Was soll er denn sonst darunter meinen, da fällt mir echt nichts ein 😞

    Dann mal wieder: Wenn man keine Ahnung hat, … Den Rest kennst du mittlerweile bestimmt auswendig.



  • Ich hätt das jetzt von der anderen Seite aufgezogen. Beispielsweise

    #include <iostream>
    
    int main() {
      int a, b, c;
    
      std::cin >> a >> b >> c;
    
      int kleinstes = a;
      int groesstes = a;
    
      if(b < kleinstes) { kleinstes = b; }
      if(c < kleinstes) { kleinstes = c; }
    
      if(b > groesstes) { groesstes = b; }
      if(c > groesstes) { groesstes = c; }
    
      int mitte = a + b + c - kleinstes - groesstes;
    
      std::cout << kleinstes << " <= " << mitte << " <= " << groesstes;
    }
    

    ...wobei das mit Funktionen (min, max bspw.) natürlich noch hübscher geht.



  • Das lässt sich mit einem Sortiernetz lösen (hier Bubblesort) - angenommen, std::swap ist erlaubt 😃

    #include <iostream>
    #include <algorithm>
    
    int main()
    {
            int a, b, c;
            std::cin >> a >> b >> c;
    
            if(a < b) std::swap(a, b);
            if(b < c) std::swap(b, c);
            if(a < b) std::swap(a, b);
    
            std::cout << a << ", " << b << ", " << c;
    }
    

    .



  • max(a,b) = (|a+b| + |a-b|)/2;
    min(a,b) = (|a+b| - |a-b|)/2
    

    Alles andere ist nur eine geschachtelte Anwendung von min/max. Weitrauming kann if auch als Vergleichsoperator aufgefasst werden.



  • Wollte wissen, ob man die Aufgabe auch ohne logische Op. (incl. Vergleichsoperatoren), ohne ifs, ohne swaps, etc. lösen kann. Gerade eben habe ich gesehen, dass knivils Lösung auch in die Richtung geht, ist aber eleganter. Schade um die Zeit, aber was soll's.

    #include<iostream>
    
    int max (int x, int y)
    {
    	return x * bool(int(x / y)) + y * bool(int(y / x)) * (bool (x-y));
    }
    
    int min (int x, int y)
    {
    	return y * bool(int(x / y)) + x * bool(int(y / x)) * (bool (x-y));
    }
    
    int main()
    {
    	int a, b, c;
    	std::cin >> a >> b >> c; 
    	int sum = a + b + c;
    
    	int smallest = min (min(a, b), min(b, c));
    	int largest = max (max(a, b), max(b, c));
    	int mid = sum - smallest - largest;
    
    	std::cout << smallest << ' ' << mid << ' ' << largest;
    }
    

    Edit: hatte die Summe vergessen.


  • Mod

    Der Cast zu bool ist aber auch nur ein gut versteckter Vergleich 🕶



  • "Betrag" ist ein verstecktes "if", genau so wie "cast nach bool" eines ist.
    Ich sehe keinen besonderen Sinn dahinter eines von beiden zu akzeptieren und gleichzeitig einen einfachen Vergleich zu verbieten.

    @knivil
    Zeig mal wie du "Betrag von" in C++ ohne if und ohne eine Funktion aufzurufen machen willst.

    @[Rewind]
    Bei x==y kommt bei dir 0 raus würde ich sagen. Und mit negativen Zahlen wird das auch nicht funktionieren.

    So wäre mal die Sache mit x==y gelöst:

    int max (int x, int y)
    {
        return x * bool(int(x / y)) + y * bool(int(y / (x+1)));
    }
    

    Negative Zahlen gehen immer noch nicht, und x darf jetzt nimmer INT_MAX sein.
    Aber naja, wie gesagt mMn. immer noch ziemlich sinnfrei, von daher...


  • Mod

    hustbaer schrieb:

    "Betrag" ist ein verstecktes "if", genau so wie "cast nach bool" eines ist.

    Für den Betrag gibt es Bittricks:
    http://graphics.stanford.edu/~seander/bithacks.html#IntegerAbs

    Ist jetzt natürlich die Frage, ob man bitweise Operationen als logische Operationen ansieht. Ich würde es nicht tun. Sie sind eher Rechenoperationen wie Addition.

    edit: Im Absatz unter dem verlinkten stehen dann auch gleich min und max ohne logische Operatoren ausgeschrieben:

    r = y + ((x - y) & ((x - y) >> (sizeof(int) * CHAR_BIT - 1))); // min(x, y)
    r = x - ((x - y) & ((x - y) >> (sizeof(int) * CHAR_BIT - 1))); // max(x, y)
    


  • hustbaer schrieb:

    @[Rewind]
    Bei x==y kommt bei dir 0 raus würde ich sagen.

    Würde ich nicht sagen. Genau aus diesem Grund multipliziere ich am Ende noch mit der Differenz der beiden Zahlen.

    hustbaer schrieb:

    Und mit negativen Zahlen wird das auch nicht funktionieren.

    Jein. Es gibt, glaube ich, nur einen Fall, wo das nicht funktioniert, und zwar wenn x + y = 0 .



  • Der Betrag im ersten Term kann weggelassen werden, dann sollte es auch fuer negative Zahlen funktionieren.

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

    Um den Absolutwert auszurechnen, kann das Sign-Bit pauschal auf 0 gesetzt werden. Spielchen mit Zweierkomplement sind auch moeglich.



  • Sone schrieb:

    Ich stelle mich nicht doof! Was soll er denn sonst darunter meinen, da fällt mir echt nichts ein 😞

    < ist aber kein logischer, sondern ein relationaler Operator.



  • Tachyon schrieb:

    Sone schrieb:

    Ich stelle mich nicht doof! Was soll er denn sonst darunter meinen, da fällt mir echt nichts ein 😞

    < ist aber kein logischer, sondern ein relationaler Operator.

    Wenn das so ist, dann erzählt deutsches Wiki mal wieder Schrott 😡


Log in to reply