Bestimmen der größten und kleinsten Zahl mit möglichst wenig if verknüpfungen



  • Ich schreibe einen Code der bei 4 eingegebenen Zahlen jeweils die größte und kleinste ausgibt.
    Bedingung dabei ist das es nur 4 mal if enthält.
    Ich habe schon einen Ansatz aber dabei komme ich niemals nur auf 4 if:

    
    int main(void) {
    
        int  a, b, c, d;                                             
    
    
        printf("Vier ganze Zahlen eingeben: ");
    
        scanf_s("%2d%2d%2d%2d", &a, &b, &c, &d);                                                         
    
        if (a > b && a > c && a > d && b > c && b > d)
        {
            printf("Groesste  Zahl : %d\n", a);
            printf("Kleinste  Zahl : %d\n", b);
        }
        if else (b > a && b > c && b > d && a > c && a > d)
        {
            printf("Groeßte  Zahl : %d\n", b);
            printf("Kleinste  Zahl : %d\n", a);
        }
        
    
    
    
    
    }
    
    

    kann mir da einer vielleicht bei weiterhelfen?


  • Mod

    Versuche nicht, alles in einer einzigen Abfrage herauszufinden. Vergleichst du Zahl1 mit Zahl2, weißt du, welche von den beiden größer (oder kleiner) ist. Vergleichst du Zahl3 mit Zahl4, weißt du, welche von beiden größer (oder kleiner) ist. Vergleichst du dann den größeren von Zahl1/Zahl2 mit dem größeren von Zahl3/Zahl4, dann ist der größere von beiden auch der größte von allen Zahlen. Ebenso mit den kleineren.



  • Wobei es schon nicht ganz trivial ist wenn man beides (grösste und kleinste) mit nur 4 if's insgesamt finden will. Da muss man schon ein bisschen mitdenken/kreativ sein.

    (Also angenommen dass Schleifen auch verboten sind. Wenn Schleifen und z.B. Arrays erlaubt sind, dann ist es einfach.)
    ((Und natürlich wenn Hilfsfunktionen erlaubt sind, dann ist es auch nicht so schwer.))


  • Mod

    Ich vermute von der Anforderung her, dass hier keine Schleifen erwartet werden, denn dann sind 4 Vergleiche genau das, mit dem man gerade so minimal auskommt für diese spezielle Anforderung (für komplette Sortierung bräuchte man beispielsweise schon 5 Vergleiche). Es soll also wohl geprüft werden, ob der Prüfling scharf nachdenken kann und die berüchtigte Programmiererdenke drauf hat.

    Ob man es nun als Erfolg werten kann, wenn man erst durch Fragen in Fachforen auf die Lösung kommt, ist natürlich bestreitbar. Ich würde sagen, ja, denn es zeigt wichtige Praxiskompetenz 🙂



  • Mein Vorschlag wäre die folgende Funktion. Die Funktion erwartet ein Array mit vier Zahlen an den Positionen 1, 2, 3, 4. Damit es kein out of bounds Problem gibt, gibt es das Element 0, das INT_MIN sein muss. Als Ergebnis wird der Index des größten Elements zurückgeliefert oder eben 0 d.h. alle sind gleich.

    Ok, ich sehe, dass es noch ein Problem gibt, wenn Zahlen gleich sind, aber das dürfte nun ein Leichtes sein, das Problem zu beheben.

    int compare (int a[5]) {
        a[0] = INT_MIN;
    
        int t1 = a[1] > a[2];
        int t2 = a[2] > a[1];
        int s1 = t1+(2*t2);
    
        int t3 = a[3]  > a[s1];
        int t4 = a[s1] > a[3];
        int s2 = (3*t3) + (s1*t4);
    
        int t5 = a[4]  > a[s2];
        int t6 = a[s2] > a[4];
        int s3 = (4*t5) + (s2*t6);
    
        return s3;
    }
    


  • Wäre im Sinne der Aufgabe zwar gefuscht, aber man könnte auf den ? Operator verweisen, dann braucht man kein if.



  • @john-0 und nun erkläre mir bitte, was dieser Code macht.

    Verstehe mich nicht falsch, ich bin selbst seit 15 Jahren in der Programmierung - aber dein code ist nicht lesbar - zumindest nicht einfach.

    Verwende doch bitte aussagekräftige Variablennamen - das macht die Sache einfacher. Stichwort Clean Code.



  • @tbird sagte in Bestimmen der größten und kleinsten Zahl mit möglichst wenig if verknüpfungen:

    @john-0 und nun erkläre mir bitte, was dieser Code macht.

    Verstehe mich nicht falsch, ich bin selbst seit 15 Jahren in der Programmierung - aber dein code ist nicht lesbar - zumindest nicht einfach.

    Das sollte er aber sein, da es wirklich nur ein paar Codezeilen sind. Die Aufgabe war von vier Zahlen die größte herauszufinden. Wenn man zwei Zahlen in C t1 = a[1] < a[2] vergleicht, dann ist das Ergebnis auch als int interpretierbar und der Vergleich liefert immer 0 oder 1 zurück. Macht man auch noch der Vergleich andersherum t2 = a[1] > a[2] weiß man ob eine Zahl größer als die andere ist oder ob sie gleich sind.

    Damit das keinen Unfug zurückliefert (das fehlte hier im Code), schreiben wir zuerst eine der beiden Zahlen in das Arrayelement a[0].

    int greatest (int a[5]) {
        a[0] = a[1]; // Das brauchen wir nur im Fall, dass beide Zahlen gleich sind.
                     // Es ist somit egal, ob a[1] oder a[2] genommen wird.
    
        int t1 = a[1] > a[2];
        int t2 = a[2] > a[1];
    

    Es gibt nun drei mögliche Zustände, (t1 == 1, t2 == 0); (t1 == 0, t2 == 1); (t1 == 0, t2 == 0). Der Fall t1 und t2 sind null ist einfach, dann sind beide Zahlen gleich. Ist t1 eins, dann ist a[1] größer als a[2]. Man könnte jetzt einfach t1 + t2 rechnen, das würde für die beiden betrachteten Fälle gerade den Index des Feldes ergeben. Allerdings wenn t2 == 1, dann passt das noch nicht. Multipliziert man t2 noch mit dem Feldindex stimmt es.

        int s1 = t1 + (2 * t2);
    

    D.h. in s1steht nun der Index des Feldelements. Analog verfährt man mit den anderen Zahlen im Array.

    Verwende doch bitte aussagekräftige Variablennamen - das macht die Sache einfacher. Stichwort Clean Code.

    Ich denke nicht, dass das hier etwas ändern würde. Doku wäre in diesem Fall eher angesagt, aber weil hier der OP selbst nachdenken sollte, habe ich das weggelassen.

    Nachfolgend korrekt funktionierenden Code. Das sieht etwas grausig aus, wegen der Syntax für Zeiger auf Feld mit konstanter Größe. Das muss in C leider so sein.

    #include <stdio.h>
    #include <stdlib.h>
    
    void assign (int (* const p)[5], const int a, const int b, const int c, const int d) {
    	(*p)[1] = a;
    	(*p)[2] = b;
    	(*p)[3] = c;
    	(*p)[4] = d;
    }
    
    void print_array(int (* const p)[5]) {
    	printf ("\n[%3i,%3i,%3i,%3i]\n", (*p)[1], (*p)[2], (*p)[3], (*p)[4]);
    }
    
    int greatest (int (* const a)[5]) {
    	int t1, t2, s1, s2;
    
    	(*a)[0] = (*a)[1];
    
    	t1 = (*a)[1] > (*a)[2];
    	t2 = (*a)[2] > (*a)[1];
    	s1 = t1+(2*t2);
    
    	t1 = (*a)[s1] > (*a)[3];
    	t2 = (*a)[3]  > (*a)[s1];
    	s2 = (s1*t1) + (3*t2);
    
    	(*a)[0] = (*a)[s2];
    
    	t1 = (*a)[s2] > (*a)[4];
    	t2 = (*a)[4]  > (*a)[s2];
    	s1 = (s2*t1) + (4*t2);
    
    	return s1;
    }
    
    int smallest (int (* const a)[5]) {
    	int t1, t2, s1, s2;
    
    	(*a)[0] = (*a)[1];
    
    	t1 = (*a)[1] < (*a)[2];
    	t2 = (*a)[2] < (*a)[1];
    	s1 = t1+(2*t2);
    
    	t1 = (*a)[s1] < (*a)[3];
    	t2 = (*a)[3]  < (*a)[s1];
    	s2 = (s1*t1) + (3*t2);
    
    	(*a)[0] = (*a)[s2];
    
    	t1 = (*a)[s2] < (*a)[4];
    	t2 = (*a)[4]  < (*a)[s2];
    	s1 = (s2*t1) + (4*t2);
    
    	return s1;
    }
    
    int main () {
    	int arr[5];
    	int r;
    
    	assign (&arr, -10, -10, -5, -1);
    	print_array(&arr);
    	r = greatest(&arr);
    	printf("  Größter Wert: arr[%i]=%3i\n", r, arr[r]);
    	r = smallest(&arr);
    	printf("Kleinster Wert: arr[%i]=%3i\n", r, arr[r]);
    	
    	assign (&arr, 10, 10, 5, 5);
    	print_array(&arr);
    	r = greatest(&arr);
    	printf("  Größter Wert: arr[%i]=%3i\n", r, arr[r]);
    	r = smallest(&arr);
    	printf("Kleinster Wert: arr[%i]=%3i\n", r, arr[r]);
    
    	assign (&arr, 4, 3, 2, 1);
    	print_array(&arr);
    	r = greatest(&arr);
    	printf("  Größter Wert: arr[%i]=%3i\n", r, arr[r]);
    	r = smallest(&arr);
    	printf("Kleinster Wert: arr[%i]=%3i\n", r, arr[r]);
    
    	assign (&arr, 1, 2, 3, 3);
    	print_array(&arr);
    	r = greatest(&arr);
    	printf("  Größter Wert: arr[%i]=%3i\n", r, arr[r]);
    	r = smallest(&arr);
    	printf("Kleinster Wert: arr[%i]=%3i\n", r, arr[r]);
    
    	return EXIT_SUCCESS;
    }
    

Log in to reply