TL: DR; Il tuo codice è già corretto e "pulito".
Vedo un sacco di gente che gira intorno alla risposta, ma a tutti manca la foresta tra gli alberi. Facciamo l'intera scienza del computer e l'analisi matematica per comprendere completamente questa domanda.
Innanzitutto, notiamo che abbiamo 3 variabili, ciascuna con 3 stati: & lt ;, =, o & gt ;. Il numero totale di permutazioni è 3 ^ 3 = 27 stati, che assegnerò un numero univoco, indicato con P #, per ogni stato. Questo numero P # è un sistema di numeri fattoriali .
Enumerazione di tutte le permutazioni che abbiamo:
a ? b | a ? c | b ? c |P#| State
------+-------+-------+--+------------
a < b | a < c | b < c | 0| C
a = b | a < c | b < c | 1| C
a > b | a < c | b < c | 2| C
a < b | a = c | b < c | 3| impossible a<b b<a
a = b | a = c | b < c | 4| impossible a<a
a > b | a = c | b < c | 5| A=C > B
a < b | a > c | b < c | 6| impossible a<c a>c
a = b | a > c | b < c | 7| impossible a<c a>c
a > b | a > c | b < c | 8| A
a < b | a < c | b = c | 9| B=C > A
a = b | a < c | b = c |10| impossible a<a
a > b | a < c | b = c |11| impossible a<c a>c
a < b | a = c | b = c |12| impossible a<a
a = b | a = c | b = c |13| A=B=C
a > b | a = c | b = c |14| impossible a>a
a < b | a > c | b = c |15| impossible a<c a>c
a = b | a > c | b = c |16| impossible a>a
a > b | a > c | b = c |17| A
a < b | a < c | b > c |18| B
a = b | a < c | b > c |19| impossible b<c b>c
a > b | a < c | b > c |20| impossible a<c a>c
a < b | a = c | b > c |21| B
a = b | a = c | b > c |22| impossible a>a
a > b | a = c | b > c |23| impossible c>b b>c
a < b | a > c | b > c |24| B
a = b | a > c | b > c |25| A=B > C
a > b | a > c | b > c |26| A
Dall'ispezione vediamo che abbiamo:
- 3 stati dove A è il massimo,
- 3 stati dove B è il massimo,
- 3 indica dove C è il massimo e
- 4 stati in cui A = B o B = C.
Scriviamo un programma (vedere la nota a piè di pagina) per enumerare tutte queste permutazioni con i valori per A, B e C. Ordinamento stabile per P #:
a ?? b | a ?? c | b ?? c |P#| State
1 < 2 | 1 < 3 | 2 < 3 | 0| C
1 == 1 | 1 < 2 | 1 < 2 | 1| C
1 == 1 | 1 < 3 | 1 < 3 | 1| C
2 == 2 | 2 < 3 | 2 < 3 | 1| C
2 > 1 | 2 < 3 | 1 < 3 | 2| C
2 > 1 | 2 == 2 | 1 < 2 | 5| ??
3 > 1 | 3 == 3 | 1 < 3 | 5| ??
3 > 2 | 3 == 3 | 2 < 3 | 5| ??
3 > 1 | 3 > 2 | 1 < 2 | 8| A
1 < 2 | 1 < 2 | 2 == 2 | 9| ??
1 < 3 | 1 < 3 | 3 == 3 | 9| ??
2 < 3 | 2 < 3 | 3 == 3 | 9| ??
1 == 1 | 1 == 1 | 1 == 1 |13| ??
2 == 2 | 2 == 2 | 2 == 2 |13| ??
3 == 3 | 3 == 3 | 3 == 3 |13| ??
2 > 1 | 2 > 1 | 1 == 1 |17| A
3 > 1 | 3 > 1 | 1 == 1 |17| A
3 > 2 | 3 > 2 | 2 == 2 |17| A
1 < 3 | 1 < 2 | 3 > 2 |18| B
1 < 2 | 1 == 1 | 2 > 1 |21| B
1 < 3 | 1 == 1 | 3 > 1 |21| B
2 < 3 | 2 == 2 | 3 > 2 |21| B
2 < 3 | 2 > 1 | 3 > 1 |24| B
2 == 2 | 2 > 1 | 2 > 1 |25| ??
3 == 3 | 3 > 1 | 3 > 1 |25| ??
3 == 3 | 3 > 2 | 3 > 2 |25| ??
3 > 2 | 3 > 1 | 2 > 1 |26| A
Nel caso ti stavi chiedendo come sapevo quali stati P # erano impossibili, ora lo sai. :-)
Il numero minimo di confronti per determinare l'ordine è:
Log2 (27) = Log (27) / Log (2) = ~ 4,75 = 5 confronti
vale a dire. coredump ha dato il corretto 5 numero minimo di confronti. Vorrei formattare il suo codice come:
status_t index_of_max_3(a,b,c)
{
if (a > b) {
if (a == c) return DONT_KNOW; // max a or c
if (a > c) return MOSTLY_A ;
else return MOSTLY_C ;
} else {
if (a == b) return DONT_KNOW; // max a or b
if (b > c) return MOSTLY_B ;
else return MOSTLY_C ;
}
}
Per il tuo problema non ci interessa testare l'uguaglianza, quindi possiamo omettere 2 test.
Non importa quanto sia pulito / cattivo il codice se riceve la risposta sbagliata, quindi questo è un buon segno che stai gestendo correttamente tutti i casi!
Successivamente, per quanto riguarda la semplicità, le persone continuano a provare a "migliorare" la risposta,
dove pensano che migliorare significa "ottimizzare" il numero di confronti,
ma non è esattamente quello che stai chiedendo. Hai confuso tutti dove hai chiesto
"Sento che potrebbe esserci un miglioramento" ma non ho definito cosa significa "meglio". Meno confronti? Meno codice? Confronti ottimali?
Ora, poiché stai chiedendo la leggibilità del codice (per correttezza), apporterei solo una modifica al tuo codice per la leggibilità: allinea il primo test con gli altri.
if (a > b && a > c)
status = MOSTLY_A;
else if (b > a && b > c)
status = MOSTLY_B;
else if (c > a && c > b)
status = MOSTLY_C;
else
status = DONT_KNOW; // a=b or b=c, we don't care
Personalmente lo scriverei in questo modo, ma questo potrebbe essere troppo poco ortodosso per i tuoi standard di codifica:
if (a > b && a > c) status = MOSTLY_A ;
else if (b > a && b > c) status = MOSTLY_B ;
else if (c > a && c > b) status = MOSTLY_C ;
else /* a==b || b ==c*/status = DONT_KNOW; // a=b or b=c, we don't care
Nota a margine: questo è il codice C ++ per generare le permutazioni:
#include <stdio.h>
char txt[] = "< == > ";
enum cmp { LESS, EQUAL, GREATER };
int val[3] = { 1, 2, 3 };
enum state { DONT_KNOW, MOSTLY_A, MOSTLY_B, MOSTLY_C };
char descr[]= "??A B C ";
cmp Compare( int x, int y ) {
if( x < y ) return LESS;
if( x > y ) return GREATER;
/* x==y */ return EQUAL;
}
int main() {
int i, j, k;
int a, b, c;
printf( "a ?? b | a ?? c | b ?? c |P#| State\n" );
for( i = 0; i < 3; i++ ) {
a = val[ i ];
for( j = 0; j < 3; j++ ) {
b = val[ j ];
for( k = 0; k < 3; k++ ) {
c = val[ k ];
int cmpAB = Compare( a, b );
int cmpAC = Compare( a, c );
int cmpBC = Compare( b, c );
int n = (cmpBC * 9) + (cmpAC * 3) + cmpAB; // Reconstruct unique P#
printf( "%d %c%c %d | %d %c%c %d | %d %c%c %d |%2d| "
, a, txt[cmpAB*2+0], txt[cmpAB*2+1], b
, a, txt[cmpAC*2+0], txt[cmpAC*2+1], c
, b, txt[cmpBC*2+0], txt[cmpBC*2+1], c
, n
);
int status;
if (a > b && a > c) status = MOSTLY_A;
else if (b > a && b > c) status = MOSTLY_B;
else if (c > a && c > b) status = MOSTLY_C;
else /* a ==b || b== c*/status = DONT_KNOW; // a=b, or b=c
printf( "%c%c\n", descr[status*2+0], descr[status*2+1] );
}
}
}
return 0;
}
Modifiche: in base al feedback, spostato TL: DR in alto, rimossa tabella non ordinata, chiarito 27, ripulito il codice, descritto stati impossibili.