Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: DickGumshoe en 13 Noviembre 2011, 19:54 pm



Título: ¿Es posible intercambiar dos valores sin usar variable auxiliar?
Publicado por: DickGumshoe en 13 Noviembre 2011, 19:54 pm
Hola.

Me han planteado dos preguntas. La primera la sé responder.

1. ¿Es posible intercambiar dos valores?

Y yo creo que sí, ya que haciendo lo siguiente en C, me intercambia los valores:

aux=a
a=b
b=aux

Por ejemplo, si a=4 y b=5; con esto será b=4 y a=5, por lo que he comprobado que esa respuesta es correcta.

Ahora viene la segunda pregunta, que es la que no sé...

2. ¿Es posible intercambiar dos valores sin utilizar una variable auxiliar?

En el caso anterior, utilicé la variable "aux", para poder intercambiar los valores de a y b, pero ahora el enunciado dice que no puedo utilizarla.

He probado a poner
a=b
b=a
,pero claro, al poner a=b, en b=a ya estoy diciendo que a=a, por lo que no es correcto.

También he probado con

((a=b) & (b=a)), pero tampoco...

Y bueno, ya en un papel tengo varias posibilidades más, pero son erróneas también...

¿Alguien podría explicarme si es posible?

Muchísimas gracias.


Título: Re: ¿Es posible intercambiar dos valores sin usar variable auxiliar?
Publicado por: raul338 en 13 Noviembre 2011, 19:57 pm
Código
  1. Private Sub lSwap(ByRef lVal1 As Long, ByRef lVal2 As Long)
  2.    '   //  Intercambia {lVal1} por {lVal2} y {lVal2} a {lVal1} sin variable temporal
  3.    lVal1 = lVal1 Xor lVal2
  4.    lVal2 = lVal2 Xor lVal1
  5.    lVal1 = lVal1 Xor lVal2
  6. End Sub
  7.  

Fuente: http://foro.elhacker.net/vb/recopilacion_de_funciones_con_operaciones_binarias-t329680.0.html (http://foro.elhacker.net/vb/recopilacion_de_funciones_con_operaciones_binarias-t329680.0.html)


Título: Re: ¿Es posible intercambiar dos valores sin usar variable auxiliar?
Publicado por: DickGumshoe en 13 Noviembre 2011, 20:37 pm
Código
  1. Private Sub lSwap(ByRef lVal1 As Long, ByRef lVal2 As Long)
  2.    '   //  Intercambia {lVal1} por {lVal2} y {lVal2} a {lVal1} sin variable temporal
  3.    lVal1 = lVal1 Xor lVal2
  4.    lVal2 = lVal2 Xor lVal1
  5.    lVal1 = lVal1 Xor lVal2
  6. End Sub
  7.  

Fuente: http://foro.elhacker.net/vb/recopilacion_de_funciones_con_operaciones_binarias-t329680.0.html (http://foro.elhacker.net/vb/recopilacion_de_funciones_con_operaciones_binarias-t329680.0.html)

Ah, muchísimas gracias, ya lo entiendo.

Saludos.

P.D.: También he sacado la fórmula de

a=a+b
b=a-b
a=a-b

Muchas gracias.


Título: Re: ¿Es posible intercambiar dos valores sin usar variable auxiliar?
Publicado por: BlackZeroX en 13 Noviembre 2011, 20:56 pm
También he sacado la fórmula de

a=a+b
b=a-b
a=a-b


Con eso provocarias un OverFlow con valores grandes...

Código
  1.  
  2. inline void swap(void* pv1, void* pv2) {
  3.    *((int*)pv1) ^= *((int*)pv2);
  4.    *((int*)pv2) ^= *((int*)pv1);
  5.    *((int*)pv1) ^= *((int*)pv2);
  6. }
  7.  
  8.  

o

Código
  1.  
  2. #define swap(pv1,pv2) pv1 ^= pv2; pv2 ^= pv1; pv1 ^= pv2;
  3.  
  4.  

Te recomiendo la macro...

Dulces Lunas!¡.


Título: Re: ¿Es posible intercambiar dos valores sin usar variable auxiliar?
Publicado por: DickGumshoe en 13 Noviembre 2011, 21:10 pm
Con eso provocacias un OverFlow con valores grandes...

Código
  1.  
  2. inline void swap(void* pv1, void* pv2) {
  3.    *((int*)pv1) ^= *((int*)pv2);
  4.    *((int*)pv2) ^= *((int*)pv1);
  5.    *((int*)pv1) ^= *((int*)pv2);
  6. }
  7.  
  8.  

o

Código
  1.  
  2. #define swap(pv1,pv2) pv1 ^= pv2; pv2 ^= pv1; pv1 ^= pv2;
  3.  
  4.  

Dulces Lunas!¡.

Ya... Lo que pasa que el código del "xor" todavía no lo he dado (tengo 13 años y estoy estudiando con unos apuntes que hay en una web), así que por ahora no lo podré hacer así. Cuando llegue a esa parte, usaré el otro código.

Muchas gracias a todos.


Título: Re: ¿Es posible intercambiar dos valores sin usar variable auxiliar?
Publicado por: rir3760 en 14 Noviembre 2011, 02:50 am
2. ¿Es posible intercambiar dos valores sin utilizar una variable auxiliar?
Tal vez si o tal vez no (depende del tipo de valor y de los objetos en cuestión). Ese es el problema: ya que no hay una forma realmente genérica para realizar el intercambio (al menos no en C estándar) lo mejor es utilizar una variable temporal y dejarle el resto al compilador.


También he probado con

((a=b) & (b=a)), pero tampoco...
Te recomendaría que no hicieras eso: "tasajear" código para "ver que pasa" y en base al resultado sacar conclusiones. Ello porque si cometes un error en C eso resulta en "comportamiento no definido", en buen cristiano cualquier cosa puede pasar, por ejemplo:

A) El programa revienta
B) Se quema la PC
C) Te deja la novia/amiga con privilegios/etc.
D) Lo peor: todo funciona de maravilla.

Es usualmente el ultimo caso el que da problemas: le das el programa a tu profesor/tutor/etc. y resulta que el bendito programa no funciona en su PC.

Mejor consigue un buen libro y aprende en base a el (y foros como este).

Un saludo


Título: Re: ¿Es posible intercambiar dos valores sin usar variable auxiliar?
Publicado por: DickGumshoe en 14 Noviembre 2011, 15:21 pm
Tal vez si o tal vez no (depende del tipo de valor y de los objetos en cuestión). Ese es el problema: ya que no hay una forma realmente genérica para realizar el intercambio (al menos no en C estándar) lo mejor es utilizar una variable temporal y dejarle el resto al compilador.

Te recomendaría que no hicieras eso: "tasajear" código para "ver que pasa" y en base al resultado sacar conclusiones. Ello porque si cometes un error en C eso resulta en "comportamiento no definido", en buen cristiano cualquier cosa puede pasar, por ejemplo:

A) El programa revienta
B) Se quema la PC
C) Te deja la novia/amiga con privilegios/etc.
D) Lo peor: todo funciona de maravilla.

Es usualmente el ultimo caso el que da problemas: le das el programa a tu profesor/tutor/etc. y resulta que el bendito programa no funciona en su PC.

Mejor consigue un buen libro y aprende en base a el (y foros como este).

Un saludo

Bueno, eso lo hice pensando, solo que no era correcto, y por eso daba error. En realidad no metí eso por probar.

Muchas gracias a todos por haber resuelto mi duda ^^