2012-09-02 3 views
2

éditer: Sur un changement impair que quelqu'un lit ceci, je voudrais ajouter une dernière chose. En supposant que les trois valeurs en question sont déjà en mémoire et qu'elles ne sont pas modifiées, j'ai compté pas moins de 14 instructions pour pouvoir réaliser cet exploit.Algorithme le plus efficace pour trouver la plus grande et la plus petite des trois valeurs

Je ressemble beaucoup à ceci confirmé si quelqu'un peut.

[fin d'édition haut]

Le problème est simple. J'ai trois valeurs entières et j'ai besoin de trouver le plus grand et le plus petit. Par le plus grand, je veux dire pas le plus petit ou entre et vice versa.

Comme je ne trouvais pas de «solution de qualité» en ligne, j'ai dû faire ma propre tentative.

if(a > b) { 
    if(a > c) { 
    high = a; 
    if(b > c) { 
     low = c; 
    } 
    else { 
     low = b; 
    } 
    } 
    else { 
    if(b > c) { 
     high = b; 
     low = c; 
    } 
    else { 
     high = c; 
     low = b; 
    } 
    } 
} 
else if(a > c) { 
    if(b > c) { 
    high = b; 
    low = c; 
    } 
    else { 
    high = c; 
    low = b; 
    } 
} 
else { 
    low = a; 
    if(b > c) { 
    high = b; 
    } 
    else { 
    high = c; 
    } 
} 

En supposant que je n'ai fait aucune erreur, cela devrait résoudre le problème en utilisant trois conditions. En supposant que cela fonctionne comme prévu, je suis plutôt satisfait de mon effort, mais mon intention était de trouver l'algorithme le plus efficace, donc je vous demande maintenant ce que c'est.

Cordialement.

Éditer: J'ai passé en revue les solutions proposées jusqu'ici et elles sont toutes agréables.

Mon préféré jusqu'ici.

if(a>b) { 
    max = a; 
    min = b; 
} 
else { 
    max = b; 
    min = a; 
} 
if(c>max) 
    max = c 
else if(c< min) 
    min = c 

2-3 sigments et 2-3 conditions, si je ne me trompe pas. C'est impressionnant.

petite révision de ce qui précède, en utilisant 'a' comme alias pour 'min'.

if(a>b) { 
    max = a; 
    a = b; 
} 
else { 
    max = b; 
} 
if(c>max) 
    max = c 
else if(c< a) 
    a = c 

Si seulement il y avait un moyen facile d'échanger des variables ... Eh bien, la seule chose que je peux penser est que cela pourrait éliminer le besoin de « max », au moins dans les dérivés C et C, certainement wouldn ne pas être efficace, sauf en termes d'utilisation de la mémoire, et je peux m'attendre à dépenser 4 octets supplémentaires. ;)

+2

« mais mon intention l'ion était de trouver l'algorithme le plus efficace "Le plus efficace en termes de quoi? Moins de mémoire utilisée? Temps d'exécution moyen le plus rapide? Le temps d'exécution du pire cas le plus rapide? Moins de comparaisons? Moins de lignes de code? –

+1

Pour quelle entrée cela fonctionne-t-il avec seulement deux conditions? – Deestan

+0

Mon erreur, il n'y a pas de scénario avec seulement deux conditions. Quant à ce que je veux dire par le plus efficace ... Peut-être que j'aurais dû utiliser le mot "intelligent" à la place. Je pourrais dire d'un point de vue mathématique, impliquant le moins d'étapes ou la solution la plus élégante. – Zacariaz

Répondre

3
def min_max(a, b, c): 
    if a > b: 
     min, max = b, a # two assignments 
    else: 
     min, max = a, b # ditto 

    if c > max: 
     max = c 
    elif c < min: 
     min = c 

    return (min, max) 
+0

Même approche que mon favori précédent, seulement plus intelligent avec les affectations. Merci – Zacariaz

4

Puisque vous avez seulement 3 j'utiliser quelque chose comme:

Maximum = max(a, max(b,c)) 
Minimum = min(a, min(b,c)) 

Je ne suis pas sûr de ce que la langue que vous utilisez, mais la plupart de chaque langue a une fonction max, intégrée ou facilement accessible.

+0

Si vous définissez la phrase, "mon intention était de trouver l'algorithme le plus efficace" comme signifiant "le moins de comparaisons" que sure. Je pensais qu'il voulait dire la longueur de code la plus courte et la moins complexe. – mjgpy3

+0

J'aime celui-ci parce qu'il est facile à comprendre. Donc, à moins que ce soit pour une sorte de logiciel embarqué en temps réel - je pense que ce serait la meilleure option – Gir

+0

Il est concis et facile à comprendre, mais il utilise 4 comparés, alors que seulement 3 sont vraiment nécessaires. –

2

Peut-être

highest = a; lowest = a; 
if (b>a) 
{ 
    highest = b; 
} 
else 
{ 
    lowest = b; 
} 
if (c>highest) 
{ 
    highest = c; 
} 
else 
{ 
    if (c<lowest) 
    { 
     lowest = c; 
    } 
} 
+0

n'y at-il pas quelque chose qui ne va pas? – Zacariaz

+0

Seulement une erreur de copier-coller. – podiluska

+0

J'ai supposé autant. Solution intelligente. – Zacariaz

3
if(a>b){swap(a,b); /* in other words: a=a^b;b=a^b;a=a^b; */} 
if(a>c){swap(a,c); /*in other words: a=a^c;c=a^c;a=a^c; */} 
if(b>c){swap(b,c); /*in other words: b=b^c;c=b^c;b=b^c; */} 
//now a is the smallest, c is the largest, but names are changed 
high=c; 
low=a; 

Si vous êtes désespéré,

void swap(int & x, int & y) //<--- yes it needs to be pass by reference 
{ 
    __asm 
    { 
     movaps xmm5,[x] 
     movaps xmm6,[y] 
     movaps [x],xmm6 
     movaps [y],xmm5 //i cant say anything without trying ^^ 
    } 

    return; 

} 

seulement 3 comparaisons = moins prédictions mal branche cpu et instruction de boucle totale sera assez petit pour tenir dans un cpu -loop-cache (cache d'installation décodée)

+2

Bon - mais le gimmick d'échange XOR n'est pas seulement mauvais mais aussi très inefficace. –

+0

Je sais :), vient d'ajouter pour remplir la zone vide. Aurait pu utiliser SIMD dans un __asm ​​{} aussi (peut-être que xchg est suffisant). Oui tu as raison mais c'est efficace en terme d'espace je pense :) –

+0

N'avais pas pensé à ça. Essentiellement, la même chose que je fais, sauf que c'est, comme déjà mentionné, tout à fait inefficace. ;) – Zacariaz

1

Ceci utilise 3 comparaisons et 3 ou 4 affectations.

min = max = a; 

if a < b 
    max = b 
else 
    min = b 

if b < c 
    if c > a: 
     max = c 
else 
    if c < a: 
     min = c 
+0

Très intelligent et avec seulement deux affectations supplémentaires. – Zacariaz

0

Un commutateur calculé/énuméré devrait donner le compilateur suffisamment de liberté pour minimaliser la quantité de (conditionnel) sauts:

#include <stdio.h> 

static inline void minmax3(int*themin,int*themax, int a, int b, int c) 
{ 
switch(
      1 * (a>b) 
     + 2 * (a>c) 
     + 4 * (c>b) 
     ) { 
     case 0: *themin = a; *themax = b; break; 
     case 1: *themin = b; *themax = a; break; 
     case 2: *themin = c; *themax = b; break; 
     case 3: *themin = b; *themax = a; break; 
     case 4: *themin = a; *themax = c; break; 
     case 5: *themin = b; *themax = c; break; 
     case 6: *themin = b; *themax = c; break; 
     case 7: *themin = b; *themax = a; break; 
     } 
return ; 
} 

int main(void) 
{ 
int a,b,c,mi,ma; 

for (a=0; a <3; a++) { 
     for (b=0; b <3; b++) { 
       for (c=0; c <3; c++) { 

         minmax3(&mi, &ma, a, b, c); 
         printf("a=%d b=%d c=%d min=%d max=%d\n" 
         , a, b, c, mi, ma 
         ); 
     }}} 
return 0; 
} 
0
if(a>=b) 
{if(a>=c) 
    {MAX=a; 
    MIN=c; 
    if(c>=b) 
    MIN=b; 
    } 
    else 
    MAX=c,MIN=b; 
} 
else 
{if(b>=c) 
    {MAX=b; 
    MIN=c 
    if(c>=a) 
    MIN=a; 
    } 
    else 
    MAX=c,MIN=a; 
} 
1

Cette solution utilise entre 2-3 comparaisons.

La valeur de retour est le couple (min, max).

  • Choisissez 2 nombres des 3 nombres donnés. Comparez-les, et appelons le plus petit a et le plus grand b. Nous appelons le numéro qui n'a pas été choisi c.
  • Si c> = b alors retour (a, c).
  • Si c> = a alors retourner (a, b).
  • retour (c, b).
+0

Je dois admettre que cela me déroute. – Zacariaz

+0

Je vais modifier la réponse. –

-1

si (num1> num2 & & num1> num3) puis -> num1 est le plus grand

else if (num2> num1 & & num2> num3) puis -> num2 est le plus grand

autre puis -> num3 est le plus grand

Questions connexes