Sortieren Sie 3 Zahlen ohne Verwendung von logischen Operatoren.



  • 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 😡



  • out schrieb:

    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 😡

    Ist aber so. Logische Operatoren haben typischerweise Wahrheitswerte als Operanden. Die englische Wikiseite hat eine korrekte Auflistung.



  • Hä? Logische Operatoren sind einfach nur Operatoren, die einen Wahrheitswert liefern. Und darunter fallen halt auch relationale Operatoren.

    < ist also ein logischer Operator. Speziell halt nur ein relationaler.



  • Incocnito schrieb:

    Logische Operatoren sind einfach nur Operatoren, die einen Wahrheitswert liefern.

    Nein, logische Operatoren modellieren Verknüpfungen der Aussagenlogik. In C++ wären das Konjunktion (Und), Disjunktion (Oder) und Negation (Nicht).



  • out schrieb:

    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 😡

    Seit wann gibt man was auf Wikipedia wenn die Infos wirklich richtig sein sollen?


Anmelden zum Antworten