3 Zahlen Sortieren ohne logische Operatoren
-
Wollte nicht den alten Thread ausgraben..
https://www.c-plusplus.net/forum/91070-full#include <iostream> using namespace std; int main() { int a,b,c; cout<<"Gib drei Zahlen zw. 0 und 999 ein"<<endl; cin>>a>>b>>c; int x=a, y=b, z=c; for(int i=0; i=999; i++){ x=x--; y=y--; z=z--; if(x); else{ cout<<a; x=999; } if(y); else{ cout<<b; y=999; } if(z); else{ cout<<c; z=999; } } return 0; }Weiß jemand wieso das nicht funktioniert? Programm gibt seitenweise Zahlen aus.
Dabei sollte meiner Meinung doch nur eine Zahl ausgegeben werden wenn x, y, oder z 0 erreicht hat. Und das nur einmal, da dann ja die Variablen wieder hochgesetzt werden und somit im nächsten Durchlauf >0 sind.
mfg CS
-
i=999?
-
Zeile 8:
=ist eine Zuweisung, kein Vergleich. Außerdem wäre ein Vergleich hier sowieso falsch. Und fällt vermutlich unter die Definition einer logischen Operation. Ebenso ist eine for-Schleife an sich bloß syntaktischer Zucker für etwas, was man logische Operation nennen könnte (was auch immer das genau heißen mag bei dir).
Zeilen 9-11: Undefiniertes Verhalten.
Zeilen 12, 17 und 21 fallen wahrscheinlich unter die Definition einer logischen Operation.Insgesamt finde ich deine Lösungsidee nicht gut. Sowohl verwendest du lauter Dinge, die man als logische Operation bezeichnen würde; verbrauchst ungeheuer viel Rechenzeit für solch eine simple Operation; und du bist in der Eingabemenge auf einen kleinen, vorgegebenen Zahlenbereich beschränkt.
Wenn du genauer erläuterst, was erlaubt ist und was nicht, kann man dir sicherlich was besseres vorschlagen. Allgemein kann man jedenfalls das Minimum/Maximum zweier Zahlen durch ein paar clevere Rechenoperationen finden. Die Erweiterung auf das Sortieren dreier Zahlen ist dann simpel und vermutlich eher der Lösungsweg, den euer Lehrer sehen möchte.
-
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 sowasint 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.
-
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.
-
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 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 -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_MAXum keine größeren Werte als 1 zu bekommen ist genau das was ich gesucht habe.
Danke!
-
@Ramanujan
DeinegreaterThanFunktion 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); } //...