3 Zahlen Sortieren ohne logische Operatoren



  • Danke das = ist natürlich Blödsinn.
    Aber du hast natürlich recht auch in der for Schleife werden logische Op. angewendet. Das kann dann wohl nicht richtig sein.

    In der Angabe ist leider nicht genau definiert was unter log. Op. zu verstehen ist und was nicht. Könnte mir schon vorstellen, dass if(a) als "Trick" gemeint ist.

    Gehen wir einmal davon aus, dass wirklich keine log. Op. erlaubt sind - über Rechenoperationen wäre ohnedies um einiges eleganter.
    Bei Überlegungen wie das funktionieren könnte, dachte ich an etwa sowas

    int a,b;
    cin>>a>>b;
    cout<<a*int(b/a)/int(b/a)<<b<<a*int(a/b)/int(a/b)<<endl;
    

    Dadurch wäre ein Mechanismus vorhanden, der falls der eine Wert größer ist eine Null erzeugt int(b/a), im anderen Fall würde der Wert unverändert bleiben. Offensichtliches Problem ist natürlich, dass wir im ersten Fall noch durch Null dividieren müssen. Mir fällt keine Mechanismus ein wie man das umgehen könnte.

    Hast du oder jemand anders eine Idee wie solche "cleveren Rechenoperationen" aussehen könnten?

    mfg CS

    btw. warum ist 9-11 undefiniert?



  • Erstmal in Zeile 12, 17 und 22 willst du wahrscheinlich kein Semicolon hinter dem if.

    Und Ausdrücke wie

    a = a++;
    

    sind deswegen undefiniert, weil a zwar inkrementiert wird, jedoch das Ergebnis vorher ausgewertet wird. Und nun weist du das alte Ergebnis der Variable selbst wieder zu, obwohl diese schon angefasst wurde.
    Was soll passieren? Soll a den Wert von a (also den alten) haben? Oder den Wert a+1 (also den neuen)?

    Und undefiniert heisst hier in der Praxis bei dir, jeder Compiler könnte ein adneres Ergebnis ausspucken dafür.


  • Mod

    Und undefiniert heisst hier in der Praxis bei dir, jeder Compiler könnte ein adneres Ergebnis ausspucken dafür.

    Psst, gleich kommt SeppJ und erzählt dir etwas über Pizzas oder so.



  • Danke, ok eine Zuweisung eines Postdekrements an sich selbst ergibt wirklich keinen Sinn. Also ist

    x=x--;
    

    nicht äquvialent zu

    x--;
    

    , sondern unterschiedliche Compiler verarbeiten diesen Befehl unterschiedlich?

    Die Semikolons nach dem if stören nicht (bzw. sind ja nötig oder?). Ich will im Fall, dass die bedingung erfüllt ist ja, dass genau nichts passiert.


  • Mod

    Danke, ok eine Zuweisung eines Postdekrements an sich selbst ergibt wirklich keinen Sinn.

    Das zu akzeptieren ist der erste Schritt. 👍

    sondern unterschiedliche Compiler verarbeiten diesen Befehl unterschiedlich?

    Sie dürfen, können, und tuns.

    Die Semikolons nach dem if stören nicht (bzw. sind ja nötig oder?).

    Warum denn nicht statt

    if(z);
            else{
                cout<<c;
                z=999;
            }
    

    einfach

    if(!z) {
                cout<<c;
                z=999;
            }
    

    😕



  • Interessante Idee, so ganz ohne logische Operatoren. Für 32 Bit lange unsigned Integer, deren Werte voneinander verschieden und 2311\le 2^{31}-1 sind, ist mir auf die Schnelle sowas hier eingefallen:

    #include <iostream>
    #include <cstdint>
    
    int main()
    {
        using namespace std;
        std::uint32_t a, b, c;
        cout << "Gib drei verschiedene Zahlen zw. 0 und " << (std::numeric_limits<std::uint32_t>::max() >> 1) << " ein" << endl;
        cin >> a >> b >> c;
    
        std::uint32_t sortiert[3];
    
        sortiert[((b - a) >> 31) + ((c - a) >> 31)] = a;
        sortiert[((a - b) >> 31) + ((c - b) >> 31)] = b;
        sortiert[((a - c) >> 31) + ((b - c) >> 31)] = c;
    
        std::cout << sortiert[0] << ", " << sortiert[1] << ", " << sortiert[2] << std::endl;
    }
    

    Müsste den Job erledigen, wenn ich nicht einen groben Denkfehler (oder UB) drin habe :D. Kann mann sicher leicht mit Divide&Conquer-Strategie in einen O(nlogn)O(n \log n)-Sortieralgorithmus für beliebig lange Arrays umwandeln, dafür fehlt mir aber grad die Muße.

    Gruss,
    Finnegan



  • Arcoth schrieb:

    Warum denn nicht ...

    if(!z) {
    

    ! ist das logische Nicht.



  • Wenn man ganz auf logische Operatoren, if sowie ?: verzichten möchte, könnte man folgendes machen:

    Die eingegeben Zahlen sind größer gleich 0 und kleiner als N_MAX.

    const int N_MAX = 1000;
    
    int greaterThan(int x, int y) {
        return (x + N_MAX) / (y + N_MAX); // + N_MAX sorgt dafür, dass nur 0 oder 1 rauskommt
    }
    
    int min(int a, int b) {
        return a * greaterThan(b,a) + b * greaterThan(a,b); // wir nehmen an, dass a != b
    }
    
    int max(int a, int b) {
        return a * greaterThan(a,b) + b * greaterThan(b,a);
    }
    
    int min(int a, int b, int c) {
        return min(min(a,b), c);
    }
    
    int max(int a, int b, int c) {
        return max(max(a,b), c);
    }
    
    int mid(int a, int b, int c) {
        return max(min(a,b), min(a,c), min(b,c)); // gibt den mittleren Wert zurück
    }
    

    Alles ungetestet.



  • Das sieht sehr gut aus Ramanujan! Der Trick mit

    + N_MAX
    

    um keine größeren Werte als 1 zu bekommen ist genau das was ich gesucht habe.
    Danke!



  • @Ramanujan
    Deine greaterThan Funktion macht in Wirklichkeit "greater or equal".

    Und die Annahme "a != b" ist eigentlich auch unnötig:

    const int N_MAX = 1000;
    
    int greater(int x, int y) {
        return (x + N_MAX) / (y + N_MAX + 1);
    }
    
    int greaterOrEqual(int x, int y) {
        return (x + N_MAX) / (y + N_MAX);
    }
    
    int max(int a, int b) {
        return a * greater(a, b) + b * greaterOrEqual(b, a);
    }
    
    //...
    

Anmelden zum Antworten