((smallest) && (greater than -1)) fkt
-
Du kannst alle Zahlen als
unsignedinterpretieren und diese normal sortieren. Im Zweierkomplement (auf dessen Vorhandensein du dich dabei verlassen musst) ist jede negative Zahl (in etwa) das komplement der positiven, damit es eindeutig bleibt sind das die einzigen Zahlen, bei denen das höchste Bit gesetzt ist. Aber ganz im Ernst, bei drei Zahlen kannst du dir auch einfach die Arbeit machen und den Kram ausschreiben:
int babäm (int a, int b, int c) { if (a < 0) if (b < 0) if (c < 0) return -1; else return c; else return std::min(b, c); else if (b < 0) if (c < 0) return a; else return std::min(a, c); else if (c < 0) return std::min(a, b); else return std::min(std::min(a, b), c); }Mit uminterpretieren:
int babäääm (int a, int b, int c) { unsigned& a_ = *reinterpret_cast<unsigned*> (&a); unsigned& b_ = *reinterpret_cast<unsigned*> (&b); unsigned& c_ = *reinterpret_cast<unsigned*> (&c); unsigned res = std::min(std::min(a_, b_), c_); if (res > std::numeric_limits<int>::max()) return -1; else return int(res); }
-
Danke, die erste Lösung finde ich ziemlich unübersichtlich...
deshalb habe ich ja auch nach etwas "einfachem" ==schreibfaul gefragt
-
Und jetzt baust du einfach noch eben diese Bedingung ein und schon bist du fertig. Noch ein Tipp:
if ((a>-1) && ((b>-1) && (a<b)) && ((c>-1) && (a<c))) return a;Hoffentlich habe ich mich nicht verklammert.
Wenn ich so drüber nachdenke wäre es aber vermutlich einfacher alle Werte in einen Container sortieren und hinterher den kleinsten größer -1 zu nehmen. Das wären dann nämlich im schlimmsten Fall 3 Vergleiche zum sortieren, je nach Container eventuell noch bis zu drei Verschiebungen und danach schlimmstenfalls 3 Vergleiche mit -1 (im Falle, dass alle <-1 sind). Das sind im Schnitt vermutlich deutlich weniger Operationen als mein erster Vorschlag, der, wenn ich ihn mir jetzt angucke, vielleicht doch nicht so sauber aussieht.
-
#include <algorithm> using namespace std; int fkt(int a, int b, int c) { int ret = -1; int res = min(min(a, b), c); return res > ret ? res : ret; }
-
Ich glaube, so etwas sollte auch gehen
int _1; int _2; int _3; // ... int min = max(max(max(-1,i),max(-1,j)),max(-1,k)); if(min!=-1) { }
-
belli: genial!!!!
-
Oder aber etwas unübersichtlicher:
#include <algorithm> using namespace std; int fkt(int a, int b, int c) { return max(min(a, b), c), -1); }
-
Die Funktion von Belli liefert aber nicht das gewünschte Ergebnis oder?
a = 1;
b = -2;
c = 5;liefert -1 obwohl das Ergebis 1 sein sollte oder?
-
Jo, da hab ich wohl nur die Hälfte der Aufgabe gelesen/verstanden ...
-
Die Variablennamen waren eben falsch, ansonsten
int fkt(int a, int b, int c) { return max(max(max(-1,a),max(-1,b)),max(-1,c)); }funktioniert das immer.
-
ähmja schrieb:
Die Variablennamen waren eben falsch, ansonsten
int fkt(int a, int b, int c) { return max(max(max(-1,a),max(-1,b)),max(-1,c)); }funktioniert das immer.
Echt? Das sieht für mich aus als würde er einfach den größten Wert zurück liefern
.
-
Sorry, hab die Aufgabenstellung nur halb gelesen...
-
Hier mal was anderes:
int temp[3]={a,b,c}; std::sort(temp, temp+3); return * std::find_if(temp, temp+3, std::bind2nd(std::greater<int>(),-1))Ungetestet auf Syntaxfehler, aber um mal zu zeigen was ich oben meinte.
Pro: Einfach erweiterbar auf N-Zahlen, leicht wartbar, leicht zu verstehen
Contra: Overhead. Die Funktion wird immer noch sehr schnell sein, aber falls sie in einer zeitkritischen Schleife steht ist noch deutliche Optimierung möglich, indem man ausnutzt, dass es nur 3 Zahlen sind. sort und find sind nämlich ziemlicher Overkill um sie auf 3 Elemente anzuwenden. Eine sehr gute Implementierung von sort und ein optimierender Compiler mit Schleifenaufdröselung werden aber ein Ergebnis erzeugen, welches gleichwertig zu handgeschriebenem, optimierten Code ist. Es sollte daher also kein großer Nachteil sein. Eventuell ein eigenes, spezialisiertes sort für 3 Elemente schreiben.edit: Ups, die Bedingung für find_if war genau falsch rum. Korrigiert.
-
ähmja schrieb:
Sorry, hab die Aufgabenstellung nur halb gelesen...
Brauchst dich ja net zu entschuldigen
. Der Thread-Ersteller ist anscheinend mit den bekommenen Antworten zufrieden.Und solange er net Software entwickelt die womöglich meine Gesundheit beeinträchtigt, soll es mir auch recht sein.
-
Wieso nicht einfach
#include <algorithm> #include <limits> using namespace std; template<typename T> T getsmallestmax(T a, T b, T c, T m) { const T tmax = T(std::numeric_limits<T>::max); a=max(a,m)==m?tmax:a; b=max(b,m)==m?tmax:b; c=max(c,m)==m?tmax:c; return (a==b && a==c)?m:min(min(a,b),c); } void f() { getsmallestmax(1,2,3,-1); }
-
EDIT: Sorry, 2. Seite übersehen.
-
Da nach 4.7 (2) negative ints nach unsigned umgewandelt modulo 2^(Breite unsigned) genommen werden und dementsprechend im Ergebnis größer als von int darstellbare Werte sind, ist Folgendes möglich:
#include <algorithm> #include <limits> int minmax(int x_p, int y_p, int z_p) { unsigned x = x_p, y = y_p, z = z_p; unsigned r = std::min(x, std::min(y, z)); unsigned int_max = std::numeric_limits<int>::max(); return r <= int_max ? static_cast<int>(r) : -1; }Auf allen gängigen Rechnern ginge auch
int minmax(unsigned x, unsigned y, unsigned z) { return std::max(-1, static_cast<int>(std::min(x, std::min(y, z))); }...aber streng genommen ist die Umwandlung von unsigned nach int außerhalb des von int darstellbaren Wertebereichs implementation-defined, und man sollte sich nicht ohne Not undefiniertes Verhalten einfangen.
Der Vorteil des Ansatzes liegt darin, dass die Umwandlung von int nach unsigned in Zweierkomplementdarstellung rein konzeptuell ist und der größte Teil der Logik so auf allen gängigen Architekturen vom Compiler wegoptimiert werden kann.
-
.filmor schrieb:
int babäm (int a, int b, int c) { if (a < 0) if (b < 0) if (c < 0) return -1; else return c; else return std::min(b, c); else if (b < 0) if (c < 0) return a; else return std::min(a, c); else if (c < 0) return std::min(a, b); else return std::min(std::min(a, b), c); }´
Ich hab es jetzt mal so wie .filmor gemacht...
sein code ist zwar nicht 100% korrekt aber es funzt, auch wenn es ganz und gar nicht schön aussieht...
-
@Rumpelprogger:
assert(greatestmax(1, 1, 1, -1) == 1);@seldon:
Das hab ich vorher schonmal geschrieben und zwar so, dass der Compiler nicht über Vorzeichenverlust warnt
@threadstarter:
int babäm (int a, int b, int c) { if (a < 0) if (b < 0) if (c < 0) return -1; else return c; else if (c < 0) return b; else return std::min(b, c); else if (b < 0) if (c < 0) return a; else return std::min(a, c); else if (c < 0) return std::min(a, b); else return std::min(std::min(a, b), c); }sollte korrekt sein. Du kannst das ganze auch rekursiv mit variadic templates machen

-
Okay, in der letzten Zeile sollte
return (a==m && a==b && a==c)?m:min(min(a,b),c);stehen. Der Nachteil ist auch, dass numeric_limits<T>::max für alle Werte ebenfalls min liefert. Der Vorteil allerdings ist, dass der Min-Wert frei wählbar ist.
getsmallestmax(4.4f,4.3f,4.5f,4.35f);