El mayor y el menor de los cuatro enteros (sin matrices, sin funciones, con el menor número de sentencias ‘if’)

Verás, yo mismo he aprendido C ++ (no del todo, todavía estoy postergando -_-). Entonces, empecé la universidad y ellos están enseñando C y nos hicieron hacer un progtwig para ingresar cuatro enteros y tenemos que decirles a los más grandes y más pequeños. Simple, no?

La cosa es que ya tengo una buena comprensión de las funciones y matrices. Sí, PUEDO progtwigr esto en arreglos, no hay problema. Pero como este fue el primer laboratorio, aún no lo hemos “aprendido”, así que no puedo usar ninguno de ellos, sería muy simple con eso.

Esto es lo que escribí allí (se siente mal de alguna manera).

#include int main(void) { int first, second, third, fourth; printf("Enter four integers (separated by space): "); scanf("%d %d %d %d", &first, &second, &third, &fourth); if((first>second) && (first>third) && (first>fourth)) printf("\nFirst number is largest"); else if((second>first) && (second>third) && (second>fourth)) printf("\nSecond number is largest"); else if((third>second) && (third>first) && (third>fourth)) printf("\nThird number is largest"); else if((fourth>second) && (fourth>third) && (fourth>first)) printf("\nFourth number is largest"); if((first<second) && (first<third) && (first<fourth)) printf("\nFirst number is smallest"); else if((second<first) && (second<third) && (second<fourth)) printf("\nSecond number is smallest"); else if((third<second) && (third<first) && (third<fourth)) printf("\nThird number is smallest"); else if((fourth<second) && (fourth<third) && (fourth<first)) printf("\nFourth number is smallest"); printf("\n"); return 0; } 

Como puedes ver, es demasiado largo, aburrido y complejo. Pero viendo que todo lo que hemos cubierto en clase por ahora son bucles y declaraciones de decisiones . ¿Hay una forma más elegante de hacer esto? Uno que usa menos if s ? No es que haya algo malo en esto, pero podría ser mejor.

PS Esto no es exactamente “tarea” o algo así. Hice un progtwig, solo quería saber qué podría haber hecho para mejorarlo y aprender mejores prácticas de progtwigción.

Según la condición del OP

Pero viendo que todo lo que hemos cubierto en clase por ahora son bucles y declaraciones de decisiones . ¿Hay una forma más elegante de hacer esto? Uno que usa menos if s ?

Solo una instrucción if y una else if y un bucle for pueden hacer esta tarea. Simple y corto!

 #include  int main() { int num, max, min; printf ("Enter four numbers: "); scanf ("%d", &num); max = min = num; for (int i = 0; i < 3; i++) { scanf ("%d", &num); if (max < num) max = num; else if (min > num) min = num; } printf ("The smallest and largest of given four numbers are %d and %d respectively.\n", min, max); return 0; } 

Haga una clasificación de fusión “manual”, o bien, solo el segundo bit de la misma:

Conceptualmente, una ordenación de fusión funciona de la siguiente manera

  1. Divida la lista sin clasificar en n listas secundarias, cada una de las cuales contiene 1 elemento (una lista de 1 elemento se considera ordenada).
  2. Fusione repetidamente las sublistas para producir nuevas sublistas hasta que solo quede 1 sublista. Esta será la lista ordenada.

Fusionar ordenar ilustración de pasos de fusión

Código:

 int a = 5, b=4, c=7, d=9; int min_ab, min_cd, min; min_ab = a < b ? a : b; min_cd = c < d ? c : d; min = min_ab < min_cd ? min_ab : min_cd; printf("%d", min); 

.. y de manera similar para max.

Si lo prefiere, puede expandir el operador ternario en if (a < b) { min_ab = a; } else { min_ab = b; } if (a < b) { min_ab = a; } else { min_ab = b; } if (a < b) { min_ab = a; } else { min_ab = b; } (repartidas en varias líneas para facilitar la lectura).

La clasificación de fusión tiene una complejidad de O(n*log(n)) , por lo que debería necesitar a lo sumo O(n*log(n)) if s (consulte el artículo de wikipedia sobre clasificación de combinación ). De acuerdo con Wikipedia, "... Todos estos son tipos de comparación, y por lo tanto no pueden funcionar mejor que O (n log n) en el caso promedio o peor" ( fuente ), así que creo que esto no debería estar muy lejos en términos de número mínimo de if s .. Aunque podría intentar ver si la ejecución manual de uno de los otros algoritmos produce menos if s ;-).

Prueba algo como esto

 int main(void) { int a=-2,b=-3,c=-4,d=-5; int max=a,min=a; if(b>max){ max=b; }else if(bmax){ max=c; }else if(cmax){ max=d; }else if(d 

Manifestación

El punto principal del problema del aula que solicita encontrar el más grande y el más pequeño a la vez es enseñarle a extraer la máxima información valiosa de cada comparación.

Por ejemplo, si sabes que a > b es verdadero, de esa comparación única debes darte cuenta de que a ya no es candidato para los más pequeños y ya no debería participar en ninguna comparación dedicada a encontrar los más pequeños. Y, al mismo tiempo, debes darte cuenta de que b ya no es candidato para el más grande. Con 4 números, dos pruebas a > b c > d ya separan claramente los números en dos clases independientes: dos candidatos para el mayor y dos candidatos para el más pequeño. El rest es sencillo.

En otras palabras, la idea general es encontrar los valores extremos en paralelo , utilizando la información proporcionada por cada comparación para promover la tarea de encontrar el valor más pequeño y el más grande.

 if (first > second) { int t = first; first = second; second = t; } if (third > fourth) { int t = third; third = fourth; fourth = t; } /* Now 'first' and 'third' are candidates for the smallest, while 'second' and 'fourth' are candidates for the largest */ int min = first < third ? first : third; int max = second > fourth ? second : fourth; 

Como puede ver, esto requiere solo cuatro comparaciones para encontrar ambos números.

Tenga en cuenta que el código anterior le proporciona los valores más pequeño y más grande, pero no le indica el “índice” original del número que proporcionó cada valor. No está claro de inmediato si es realmente necesario. El texto de su pregunta no dice nada al respecto, mientras que el ejemplo de código que proporcionó lo implementa. En cualquier caso, no es difícil actualizar el código anterior para “rastrear” los orígenes de los números.

Esto es demasiado fácil, dado que los números son a, b, c, d:

 #define min(a,b) ((a) < (b) ? (a) : (b)) #define max(a,b) ((a) > (b) ? (a) : (b)) biggest = max (max(a,b), max(c,d)) smallest = min (min(a,b), min(c,d)) 

Aquí tienes, sin afirmaciones, sin funciones (aunque esta última es el requisito más estúpido y perjudicial para los adeptos que he escuchado).

Aquí hay una solución sin if if elseif o function o macro , pero con cambio de bits y sustracción en su lugar; solo usando un solo bucle for :

 #include  int main(){ int num , max, min; printf("Enter four numbers: "); scanf("%d", &num); max = min = num; for(int i = 0; i < 3; i++) { scanf("%d", &num); max = max * (1 - ( (max-num) >> 31) ) + num * ( (max-num) >> 31); min = min * (1 - ( (num-min) >> 31) ) + num * ( (num-min) >> 31); } printf("\n%d %d", max, min); return 0; } 

La operación (max-num) >> 31) captura el signo de la diferencia, que cuando se multiplica por el segundo número produce el valor mínimo de la comparación.

Esto proviene de un viejo truco de encoding SQL de los días previos a la construcción de un CASO CUANDO en ese lenguaje.

Una idea puede ser calcular el máximo y el mínimo de los dos primeros números. Luego, comparas el rest de los números en pares. El mayor de cada par se compara con el máximo actual, y el menor de cada par se compara con el mínimo actual. De esta manera, hace 3 comparaciones por cada 2 elementos, lo cual es un poco más eficiente que la respuesta de Arpit (2 comparaciones para cada elemento).

En codigo:

 #include  int main(int argc, char **argv) { int a, b, c, d; printf("Enter four integers (separated by space): "); scanf("%d %d %d %d", &a, &b, &c, &d); int max, min; if (a > b) { max = a; min = b; } else { max = b; min = a; } if (c > d) { if (c > max) { max = c; } if (d < min) { min = d; } } else { if (d > max) { max = d; } if (c < min) { min = c; } } printf("max = %d, min = %d\n", max, min); return 0; } 
 int max(int a, int b) { return a > b ? a : b; } int max_of_four(int a, int b, int c, int d) { return max(a, max(b, max(c, d))); } int main() { int a, b, c, d; scanf("%d %d %d %d", &a, &b, &c, &d); int ans = max_of_four(a, b, c, d); printf("%d", ans); return 0; } 

Este es el código C solo tiene 4 si enunciados. Mueve el número máximo a la posición d y el número mínimo a una posición. Los valores byc no están organizados correctamente dentro de una secuencia, pero como los requisitos solicitan mín. Y máx., Este código completa un trabajo:

 #include  int main() { int a, b, c, d, temp; printf("Enter four digits: "); scanf("%d %d %d %d", &a, &b, &c, &d); if ( a > b){ temp = a; a = b ; b = temp; } if ( c > d){ temp = c; c = d ; d = temp; } if ( b > d ){ temp = b; b = d; d = temp; } if ( a > c){ temp = a; a = c ; c = temp; } printf("Max %d\nMin %d\n", d, a); return 0; } 
  Please have at the following private int GetLargerValue(int num1, int num2, int num3, int num4) { int largeValue = 0; if (num1 > num2) { if (num1 > num3) largeValue = (num1 > num4) ? num1 : num4; else largeValue = (num3 > num4) ? num3 : num4; } else if (num2 > num3) largeValue = (num2 > num4) ? num2 : num4; else largeValue = (num3 > num4) ? num3 : num4; return largeValue; } 
 int max_of_four(int a, int b, int c, int d){ int res=a; if(b/res) res=b; if(c/res) res=c; if(d/res) res=d; return res; } int main() { int a, b, c, d; scanf("%d %d %d %d", &a, &b, &c, &d); int ans = max_of_four(a, b, c, d); printf("%d", ans); return 0; } 

Para un rendimiento absoluto, es decir. Mínimas comparaciones y asignaciones.

Los comentarios en cada nivel muestran los valores candidatos para min y max . La idea es reducir los conjuntos en cada nivel hasta que haya solo un elemento para cada conjunto. Esto se puede hacer con 4 comparaciones y 2 asignaciones solamente.

  // min = abcd // max = abcd if (a <= b) { // min = acd // max = bcd if ( c <= d){ // min = ac // max = bd min = a <= c ? a : c; max = b > d ? b : d; }else{ // min = ad // max = bc min = a <= d ? a : d; max = b > c ? b : c; } } else { // min = bcd // max = acd if ( c <= d){ // min = bc // max = ad min = b < c ? b : c; max = a > d ? a : d; }else{ // min = bd // max = ac min = b < d ? b : d; max = a > c ? a : c; } } 

Vi esta respuesta que se usó para el bucle y, en caso contrario, una decisión de decisión, sin embargo, publicaré una solución que supongo que se ejecutará más rápido y usará solo cuatro variables. Así que aquí va …

 #include void main() { int a,b,c,d; printf("Enter four numbers of your choice"); scanf("%d%d%d%d",&a,&b,&c,&d); a>b&&a>c?a>d?printf("%d",a):printf("%d" ,d):(b>c&&b>d)?printf("%d",b):c>d?printf("%d", c):printf("%d",d); } 
 #include  

int main (void) {

 int int_1, int_2, int_3, int_4; int pair_1_largest = 0, pair_1_smallest = 0; int pair_2_largest = 0, pair_2_smallest = 0; int quartet_largest = 0, quartet_smallest = 0; printf("Example: 15 38 8 21\n"); printf("\nEnter four integers: "); scanf("%d %d %d %d", &int_1, &int_2, &int_3, &int_4); if(int_1 > int_2) { pair_1_largest = int_1; pair_1_smallest = int_2; } else { pair_1_largest = int_2; pair_1_smallest = int_1; } if(int_3 > int_4) { pair_2_largest = int_3; pair_2_smallest = int_4; } else { pair_2_largest = int_4; pair_2_smallest = int_3; } if(pair_1_largest > pair_2_largest) quartet_largest = pair_1_largest; else quartet_largest = pair_2_largest; if(pair_1_smallest < pair_2_smallest) quartet_smallest = pair_1_smallest; else quartet_smallest = pair_2_smallest; printf("The largest number is: %d\n", quartet_largest); printf("The smallest number is: %d\n", quartet_smallest); return 0; 

}

¡Hola a todos! Soy un principiante en progtwigción, así que no seas tan duro conmigo: "¡La progtwigción de Native C" de KN King es de gran ayuda!