Utilisation de la Algorithme d'échange xor
void xorSwap (int* x, int* y) {
if (x != y) { //ensure that memory locations are different
*x ^= *y;
*y ^= *x;
*x ^= *y;
}
}
Pourquoi ce test ?
Le test consiste à s'assurer que x et y ont des emplacements mémoire différents (plutôt que des valeurs différentes). Cela est dû au fait que (p xor p) = 0
et si x et y partagent le même emplacement mémoire, lorsque l'un est mis à 0, les deux sont mis à 0. Lorsque *x et *y sont tous deux égaux à 0, toutes les autres opérations xor sur *x et *y seront égales à 0 (puisqu'elles sont identiques), ce qui signifie que la fonction mettra tous deux *x et *y à 0.
S'ils ont les mêmes valeurs mais pas le même emplacement mémoire, tout fonctionne comme prévu.
*x = 0011
*y = 0011
//Note, x and y do not share an address. x != y
*x = *x xor *y //*x = 0011 xor 0011
//So *x is 0000
*y = *x xor *y //*y = 0000 xor 0011
//So *y is 0011
*x = *x xor *y //*x = 0000 xor 0011
//So *x is 0011
Faut-il l'utiliser ?
Dans la plupart des cas, non. Le compilateur optimisera la variable temporaire et, étant donné que le swapping est une procédure courante, il devrait produire le code machine optimal pour votre plate-forme.
Prenez par exemple ce programme de test rapide écrit en C.
#include <stdlib.h>
#include <math.h>
#define USE_XOR
void xorSwap(int* x, int *y){
if ( x != y ){
*x ^= *y;
*y ^= *x;
*x ^= *y;
}
}
void tempSwap(int* x, int* y){
int t;
t = *y;
*y = *x;
*x = t;
}
int main(int argc, char* argv[]){
int x = 4;
int y = 5;
int z = pow(2,28);
while ( z-- ){
# ifdef USE_XOR
xorSwap(&x,&y);
# else
tempSwap(&x, &y);
# endif
}
return x + y;
}
Compilé en utilisant :
gcc -Os main.c -o swap
La version xor prend
real 0m2.068s
user 0m2.048s
sys 0m0.000s
Alors que la version avec la variable temporaire prend :
real 0m0.543s
user 0m0.540s
sys 0m0.000s
81 votes
Wow. Une question d'entretien mal choisie, à mon avis. Il s'agit d'une technique qui est rarement, voire jamais, utile en pratique. Il y a de fortes chances qu'elle ne fasse qu'embrouiller l'optimiseur du compilateur, ce qui aboutira à un code moins efficace qu'un "swap temporaire". À moins que l'endroit où vous avez passé votre entretien ne soit impliqué dans des activités très mathématiques (par exemple, le développement d'algorithmes de cryptage), je ne vois pas de raison valable de poser une telle question.
10 votes
En effet, cette question ne vous dit rien d'autre que si le candidat connaît cette astuce particulière qui est pratiquement inutile dans un code de production. Je suppose que vous pouvez tomber sur un magicien occasionnel qui trouve une solution à la volée, mais les personnes de ce genre qui ne connaissent pas déjà l'astuce sont probablement assez rares.
2 votes
Peut-être veulent-ils éliminer les personnes qui pensent que la connaissance de ces astuces est ce qui fait un bon programmeur ? De plus, lorsque vous lisez des articles sur l'astuce xor, faites attention aux moments où elle échoue (ce qui, selon moi, la rend complètement inutile pour l'échange d'entiers à usage général).