martes, 16 de abril de 2013

Búsqueda con recorrido secuencial

Uno de los problemas más frecuentes es el tratamiento de vectores (Array), para esto es necesario tener claros los siguientes conceptos:

- El vector es una lista de elementos, donde todos los elementos son del mismo tipo.

- El vector tiene un número de elementos fijos, cuando se crea, se reserva memoria para todos esos elementos. Por ejemplo, definimos un vector de 15 elementos de tipo unsigned char (1 byte), entonces estaremos reservando 15 bytes en la memoria.

- Es muy importante tener clara la diferencia entre posición y valor. Si el vector tiene N elementos, entonces tendremos posiciones que variarán entre 0 y N-1, y los valores en cada posición dependerán del tipo de elementos del vector.

Para el vector:

int listaNumeros [5]; //vector de 5 elementos de tipo int

Se ha reservado memoria para 5 variables de tipo int, para acceder a los valores de esas variables lo hacemos de la siguiente forma:

listaNumeros[0] = 2; //el valor en la posición 0 es 2

listaNumeros[1] = 5; //el valor en la posición 0 es 5
listaNumeros[2] = 4; //el valor en la posición 0 es 4
listaNumeros[3] = 3; //el valor en la posición 0 es 3
listaNumeros[4] = 1; //el valor en la posición 0 es 1

Se comete mucho el error de acceder a listaNumeros[5], esto dará un error de fuera de rango del vector, porque las posiciones varían entre 0 y 4, por tanto:

listaNumeros[5] = 3; //ERROR!!! no se puede realizar esta asignación porque se encuentra fuera de rango

Para buscar un elemento en un vector que cumpla ciertas características, debemos recorrer uno a uno cada elemento y determinar si el valor en cada posición cumple con las características que estamos buscando. Este recorrido uno a uno de los elementos se le denomina recorrido secuencial.

Por ejemplo, si queremos imprimir por pantalla los números del vector listaNumeros que son pares, haremos:

int N = 5;
for(int i=0; i<N; i++)
{
    //listaNumeros[i] contiene el valor en la posición i
    if(listaNumeros[i] % 2 == 0) //verifica si el valor es par, en ese caso imprime
       printf(listaNumeros[i]);
}

la variable i nos ayuda a recorrer las posiciones del vector (i varía desde 0 hasta N-1).
la variable N representa el número de elementos del vector, notar que las iteraciones del for sólo se ejecutan si i<N
La característica que buscamos es que el valor sea par, para eso utilizamos la operación % que calcula el resto de dividir listaNumeros[i] entre 2, en el caso que sea par ese resto es 0 y en ese caso imprimimos.

Si modificamos el problema y ahora sólo nos interesa mostrar el primer valor par, ¿Qué modificación tendríamos que hacer a programa anterior?

Ahora la característica no es sólo que sea par sino que además sea el primero, por tanto introducimos una variable booleana que nos indique si es el primero en encontrarse o no.

int N = 5;
boolean bPrimerPar = false
for(int i=0; i<N && !bPrimerPar; i++)
{
    //listaNumeros[i] contiene el valor en la posición i
    if(listaNumeros[i] % 2 == 0) //verifica si el valor es par, en ese caso imprime
    {   printf(listaNumeros[i]);
         bPrimerPar = true;
    }
}

Cuando se encuentra el primer valor par, la variable se vuelve true y la validación !bPrimerPar se hace falsa por tanto termina de ejecutar el bucle.

Hemos visto que se pueden realizar búsquedas en las que es necesario recorrer todos los elementos del vector y otras en las que sólo lo recorreremos hasta que encontremos el valor que estamos buscando.