Publi

Intercambiar valores

Cuando queremos hacer que una variable a sea igual a una variable b y viceversa (intercambiar los valores), lo primero que se viene a la mente, es utilizar una variable auxiliar, como en este ejemplo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
void intercambia(int *x, int *y);
int main()
{
    int a=50;
    int b=90;
    printf("a=%d t b=%dn", a, b);
    intercambia(&a, &b);
    printf("a=%d t b=%dn", a, b);
}
void intercambia(int *x, int *y)
{
    int tmp;
    tmp=*x;
    *x=*y;
    *y=tmp;
}

Aunque puede que queramos (o que nos pidan) hacerlo sin variable temporal, podemos hacer un intercambiador con sumas y restas:

1
2
3
4
5
6
void intercambia2(int *x, int *y)
{
    *x=*x+*y;           /* x=x+y */
    *y=*x-*y;           /* y=x-y */
    *x=*x-*y;           /* x=x-y */
}

Y con las propiedades de la operación XOR también podemos jugar:

1
2
3
4
5
6
void intercambia3(int *x, int *y)
{
    *x ^= *y;           /* x = x xor y */
    *y ^= *x;           /* y = y xor x */
    *x ^= *y;           /* x = x xor y */
}

Pero lo bueno de estos dos últimos métodos es que los podemos utilizar desde macros de preprocesador, y con eso nuestro código se ejecutará mucho más rápido:

1
2
3
4
5
6
7
8
9
#define interc(x,y) x=x+y; y=x-y; x=x-y;
int main()
{
    int a=-50;
    int b=40;
    printf("a=%d t b=%dn", a, b); /* a=-50 b=40 */
    interc(a, b);
    printf("a=%d t b=%dn", a, b); /* a=40 b=-50 */
}

Para ver lo rápido que se ejecuta, he hecho el programa intercambiando continuamente en un bucle for de unos 300000000 (trescientos millones) de iteraciones lo siguiente:

Para la macro de preprocesador interc(a,b),

gaspy@XiKiTiN ~/proyectos/poesiabinaria $ time ./interc
a=-50 b=40
a=-50 b=40

real 0m8.027s
user 0m7.461s
sys 0m0.022s

Para intercambia(a,b) (con variable auxiliar):

gaspy@XiKiTiN ~/proyectos/poesiabinaria $ time ./intvaux
a=-50 b=40
a=-50 b=40

real 0m8.691s
user 0m7.058s
sys 0m0.022s

Para intercambia2(a,b), con sumas y restas:

gaspy@XiKiTiN ~/proyectos/poesiabinaria $ time ./intsyr
a=-50 b=40
a=-50 b=40

real 0m12.331s
user 0m10.508s
sys 0m0.024s

Para intercambia3(a,b) con xor:

gaspy@XiKiTiN ~/proyectos/poesiabinaria $ time ./intxor
a=-50 b=40
a=-50 b=40

real 0m11.882s
user 0m10.516s
sys 0m0.031s

Por lo tanto vemos, que el método de la variable auxiliar es bastante rápido, mucho más que haciendo sumas y restas y xor (por lo tanto estos métodos no sirven de mucho, sobre todo ahora, que la memoria es barata), aunque, con las sumas y restas nos acercamos en tiempo al método de la variable auxiliar cuando lo hacemos desde una macro.

Ahora bien, es una cosa un poco sucia, pero es un buen experimento: crear una variable global c, y una macro que haga el intercambio ayudándose de la variable auxiliar c:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
#define interca(x,y) c=x; x=y; y=c;
int c;
int main()
{
    int a=-50;
    int b=40;
    long i;
    printf("a=%d t b=%dn", a, b); /* a=-50 b=40 */
    for (i=0; i<300000000; i++)
        {
            interca(a, b);
        }
    printf("a=%d t b=%dn", a, b); /* a=-50 b=40 */
}

Con éste método, obtenemos estos tiempos:

gaspy@XiKiTiN ~/proyectos/poesiabinaria $ time ./inter
a=-50 b=40
a=-50 b=40

real 0m3.087s
user 0m2.901s
sys 0m0.005s

Bastante menos 🙂 De todas formas estos tiempos son aproximados.

También podría interesarte...

There are 3 comments left Ir a comentario

  1. Pingback: Bitacoras.com /

  2. Pingback: Binary prose » Swapping variable values (examples in C) /

  3. Pingback: Operador coma – Poesía Binaria /

Leave a Reply