2010-09-05 20 views

Respuesta

14

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 mire en this. XOR es una operación muy poderosa que tiene muchos usos interesantes que surgen aquí y allá.

+1

gracias por XOR ... bt ¿El funcionamiento de XOR es más lento que cualquier otro método para resolver este problema? –

+0

@mr_eclair Permítanme probar otras manipulaciones de bit – BiGYaN

+0

@mr_eclair: en cualquier plataforma típica, no obtendrá más rápido que la sugerencia de KennyTM en la parte superior. –

13

¿Por qué no utilizar std libs?

std::swap(a,b); 
+1

Creo que el asker quiere una solución que involucre los detalles de nivel más bajo aquí, no solo llamar a una función/biblioteca lista. –

+3

@sandeepan: No es para mí o para usted que interprete cuál es la pregunta. Deberíamos responder a la pregunta formulada con la mejor solución al problema (si no es lo que requiere el OP, entonces no obtendremos una marca de verificación). Pero mantengo que esta es la mejor solución para la pregunta que se hace (incluso el OP está jugando con preguntas tontas de tipo entrevista). –

+3

@Martin No estoy de acuerdo, debemos interpretar y entender bien antes de responder y seguir pensando si hemos interpretado correctamente. Esta pregunta no se trata de una mejor solución optimizada, sino de una solución diferente. –

13

La mejor manera de intercambiar dos números sin el uso de cualquier sistema de almacenamiento temporal o operaciones aritméticas es cargar ambas variables en registros, y luego utilizar los registros al revés!

No puede hacer eso directamente desde C, pero el compilador probablemente sea bastante capaz de resolverlo (al menos, si la optimización está habilitada) - si escribe código simple y obvio, como el que KennyTM sugerido 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 la bandera -O2 optimización 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) 
-3

sólo tiene que utilizar otra cosa, por ejemplo, una variable que no es 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 cuestión no es mostrar la manera sensata de hacerlo (c=a;a=b;b=c). Es para mostrar que puedes pensar de manera original, o al menos copiar la respuesta de alguien más que sí puede.

+2

En una entrevista (de donde suele salir esta pregunta), seguramente se te pedirá que lo hagas sin usar 'argc' .. – canhazbits

17
a=a+b; 
b=a-b; 
a=a-b; 

Esto es simple pero eficaz ....

+11

Parece que contiene algunos operadores aritméticos. –

+2

Esto también es propenso al desbordamiento, a diferencia del ejemplo xor. – Mikhail

+4

@Mikhail: El desbordamiento tendrá lugar en 'a = a + b'. Luego, se realizarán dos subflujos en 'b = a-b' y' a = a-b', lo que dará como resultado que ambas variables intercambien los valores correctamente. – displayName

4

a = ((a = a + b) - (b = a - b));

3

No he visto esta solución C antes, pero estoy seguro de que alguien lo ha pensado. Y quizás tenía más autocontrol de publicación que yo.

fprintf(fopen("temp.txt", "w"), "%d", a); 
a = b; 
fscanf(fopen("temp.txt", "r"), "%d", &b); 

Sin variables adicionales!

Funciona para mí, pero dependiendo de la implementación de stdio, es posible que tenga que hacer algo con el almacenamiento en búfer de salida.

1

Usando XOR,

void swap(int &a, int &b) 
{ 
    a = a^b; 
    b = a^b; 
    a = a^b; 
} 

Un revestimiento con XOR,

void swap(int &a, int &b) 
{ 
    a ^= b ^= a ^= b; 
} 

Estos métodos parecen ser limpio, debido a que no fallan para cualquier prueba de los casos, pero de nuevo 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.

1

Además de las soluciones anteriores para un caso en el que uno de el valor está fuera de rango para un entero con signo, los dos valores de las variables se pueden intercambiar de esta manera

a = a+b; 
b=b-(-a); 
a=b-a; 
b=-(b); 
0

multiplicación y la división también se pueden utilizar.

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 
+0

Esto no funcionará si una de las variables es 0. –

1

solución simple que recuerdo de mi licenciatura :-)

a = a+b-(b=a); 

Example

Cuestiones relacionadas