c++ - valores - ¿Cómo intercambiar dos números sin usar variables temporales u operaciones aritméticas?
que es swap en java (11)
¿Por qué no usar las libretas estándar?
std::swap(a,b);
Esta ecuación intercambia dos números sin una variable temporal, pero utiliza operaciones aritméticas:
a = (a+b) - (b=a);
¿Cómo puedo hacerlo sin operaciones aritméticas? Estaba pensando en XOR.
Además de las soluciones anteriores para un caso en el que si uno de los valores está fuera de rango para un entero con signo, los valores de las dos variables se pueden intercambiar de esta manera
a = a+b;
b=b-(-a);
a=b-a;
b=-(b);
En C esto debería funcionar:
a = a^b;
b = a^b;
a = a^b;
O un refrigerador / geekier buscando:
a^=b;
b^=a;
a^=b;
Para más detalles mira en this . XOR es una operación muy poderosa que tiene muchos usos interesantes que surgen aquí y allá.
La mejor manera de intercambiar dos números sin usar ningún almacenamiento temporal o operaciones aritméticas es cargar ambas variables en registros, y luego usar los registros al revés.
No puedes hacer eso directamente desde C, pero el compilador es probablemente bastante capaz de resolverlo por ti (al menos, si la optimización está habilitada) - si escribes código simple y obvio, como el que KennyTM sugirió en su comentario .
p.ej
void swap_tmp(unsigned int *p)
{
unsigned int tmp;
tmp = p[0];
p[0] = p[1];
p[1] = tmp;
}
compilado con gcc 4.3.2 con el -O2
optimización -O2
da:
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)
No he visto esta solución C antes, pero estoy seguro de que alguien lo ha pensado. Y tal vez tenía más auto control de publicaciones que yo.
fprintf(fopen("temp.txt", "w"), "%d", a);
a = b;
fscanf(fopen("temp.txt", "r"), "%d", &b);
No hay variables extra!
A mí me funciona, pero dependiendo de la implementación de stdio, es posible que tenga que hacer algo con el búfer de salida.
Solo usa otra cosa, por ejemplo, una variable que no sea temporal. Por ejemplo,
int main (int argc, char** argv) {
int a = 5; int b = 6;
argc = a; a = b; b = argc;
}
Después de todo, el punto de la pregunta no es mostrar la forma sensata de hacerlo ( c=a;a=b;b=c
). Es para demostrar que puede pensar fuera de la caja, o al menos copiar la respuesta de alguien más que pueda.
También se puede utilizar la multiplicación y la división.
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
Utilizando XOR,
void swap(int &a, int &b)
{
a = a ^ b;
b = a ^ b;
a = a ^ b;
}
Un trazador de líneas con XOR,
void swap(int &a, int &b)
{
a ^= b ^= a ^= b;
}
Estos métodos parecen estar limpios, porque no fallan en ningún caso de prueba, pero nuevamente, ya que (como en el método 2) el valor de la variable se modifica dos veces dentro del mismo punto de secuencia, se dice que tiene un comportamiento indefinido declarado por ANSI C.
a = ((a = a + b) - (b = a - b));
a=a+b;
b=a-b;
a=a-b;
Esto es simple pero efectivo ...