Cette équation échange deux nombres sans variable temporaire, mais utilise des opérations arithmétiques:
a = (a+b) - (b=a);
Comment puis-je le faire sans opérations arithmétiques? Je pensais à XOR.
a=a+b;
b=a-b;
a=a-b;
C'est simple mais efficace ....
Pourquoi ne pas utiliser les libs std?
std::swap(a,b);
En C cela devrait fonctionner:
a = a^b;
b = a^b;
a = a^b;
OU un cooler/geekier à la recherche:
a^=b;
b^=a;
a^=b;
Pour plus de détails, regardez dans this . XOR est une opération très puissante qui a de nombreux usages intéressants ici et là.
Le meilleur moyen d'échanger deux nombres sans utiliser d'opération arithmétique ou de stockage temporaire est de charger les deux variables dans des registres, puis d'utiliser les registres à l'envers!
Vous ne pouvez pas le faire directement à partir de C, mais le compilateur est probablement tout à fait capable de le résoudre pour vous (du moins si l'optimisation est activée) - si vous écrivez un code simple et évident, tel que celui suggéré par KennyTM .
par exemple.
void swap_tmp(unsigned int *p)
{
unsigned int tmp;
tmp = p[0];
p[0] = p[1];
p[1] = tmp;
}
compilé avec gcc 4.3.2 avec l'indicateur d'optimisation -O2
donne:
swap_tmp:
pushl %ebp ; (prologue)
movl %esp, %ebp ; (prologue)
movl 8(%ebp), %eax ; EAX = p
movl (%eax), %ecx ; ECX = p[0]
movl 4(%eax), %edx ; EDX = p[1]
movl %ecx, 4(%eax) ; p[1] = ECX
movl %edx, (%eax) ; p[0] = EDX
popl %ebp ; (epilogue)
ret ; (epilogue)
Je n'avais jamais vu cette solution C auparavant, mais je suis sûr que quelqu'un y a pensé. Et peut-être eu plus de maîtrise de soi que moi.
fprintf(fopen("temp.txt", "w"), "%d", a);
a = b;
fscanf(fopen("temp.txt", "r"), "%d", &b);
Aucune variable supplémentaire!
Cela fonctionne pour moi, mais en fonction de l'implémentation de stdio, vous devrez peut-être faire quelque chose pour mettre en mémoire tampon la sortie.
a = ((a = a + b) - (b = a - b));
En utilisant XOR,
void swap(int &a, int &b)
{
a = a ^ b;
b = a ^ b;
a = a ^ b;
}
Une doublure avec XOR,
void swap(int &a, int &b)
{
a ^= b ^= a ^= b;
}
Ces méthodes semblent être propres, car elles n'échouent pas pour tous les cas de test, mais encore une fois, puisque (comme dans la méthode 2), la valeur de variable est modifiée deux fois dans le même point de séquence. On dit qu'elle a un comportement indéfini déclaré par ANSI C.
C++11
permet de:
std::swap(a, b);
std::swap_ranges(a.begin(), a.end(), b.begin());
std::tie(b, a) = std::make_Tuple(a, b);
std::tie(c, b, a) = std::make_Tuple(a, b, c);
La multiplication et la division peuvent également être utilisées.
int x = 10, y = 5;
// Code to swap 'x' and 'y'
x = x * y; // x now becomes 50
y = x / y; // y becomes 10
x = x / y; // x becomes 5
Outre les solutions ci-dessus dans le cas où, si l'une des valeurs est hors limites pour un entier signé, les valeurs des deux variables peuvent être permutées de cette manière.
a = a+b;
b=b-(-a);
a=b-a;
b=-(b);