TP: DR; Kodunuz zaten doğru ve "temiz".
Cevabın etrafında dolaşan birçok insan görüyorum ama herkes ağaçların arasından ormanı kaçırıyor. Bu soruyu tam olarak anlamak için tam bilgisayar bilimi ve matematiksel analiz yapalım.
İlk olarak, her biri 3 durumlu 3 değişkenimiz olduğunu not ediyoruz: <, = veya>. Toplam permütasyon sayısı, her bir durum için P # ile gösterilen benzersiz bir sayı atayacağım 3 ^ 3 = 27 durumdur. Bu P # numarası faktöriyel bir sayı sistemidir .
Sahip olduğumuz tüm permütasyonları numaralandırmak:
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
Muayene ile elimizde:
- 3, A'nın maks.
- 3, B'nin maks.
- 3, C'nin maks olduğu ve
- 4, A = B veya B = C'yi belirtir.
Tüm bu permütasyonları A, B ve C değerleri ile numaralandırmak için bir program yazalım (dipnota bakın). P # ile kararlı sıralama:
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
Hangi P # durumlarının imkansız olduğunu nasıl bildiğimi merak ediyorsan, şimdi biliyorsun. :-)
Siparişi belirlemek için minimum karşılaştırma sayısı:
Log2 (27) = Log (27) / Log (2) = ~ 4.75 = 5 karşılaştırma
yani coredump doğru 5 minimum sayıda karşılaştırma yaptı. Kodunu şu şekilde biçimlendiririm:
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 ;
}
}
Sorununuz için eşitlik testi yapmayı umursamıyoruz, böylece 2 testi atlayabiliriz.
Yanlış yanıtı alırsa kodun ne kadar temiz / kötü olduğu önemli değildir, bu yüzden tüm vakaları doğru bir şekilde ele aldığınızı gösteren iyi bir işarettir!
Daha sonra, basitliğe gelince, insanlar cevabı "geliştirmeye" devam ediyorlar, burada iyileştirmenin karşılaştırma sayısını "optimize etmek" anlamına geliyor, ancak bu tam olarak sorduğunuz şey değil. Herkesi “daha iyi olabileceğini hissediyorum” diye sorduğunuz yerde karıştırdınız, ancak “daha iyi” nin ne anlama geldiğini tanımlamadınız. Daha az karşılaştırma? Daha az kod mu? Optimal karşılaştırmalar?
Kod okunabilirliği hakkında soru sorduğunuzdan (doğruluk verildiğinde) okunabilirlik için kodunuzda yalnızca bir değişiklik yapacağım: İlk testi diğerleriyle hizalayın.
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
Şahsen ben şu şekilde yazardım ama bu kodlama standartlarınız için çok alışılmadık olabilir:
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
Dipnot: İşte permütasyonları oluşturmak için C ++ kodu:
#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;
}
Düzenlemeler: Geri bildirime dayanarak, TL: DR yukarı taşındı, sıralanmamış tablo kaldırıldı, 27 açıklandı, kod temizlendi, imkansız durumlar açıklandı.