Está en la página 1de 27

Algoritmos

BUSQUEDA EN C++

Bsqueda en c++
La bsqueda (searching) de informacin est relacionada con las tablas para consultar (lookup). Estas tablas contienen una cantidad de informacin que se almacena en forma de lista de parejas de datos. Por ejemplo, un diccionario con una lista de palabras y definiciones; un catalogo con una lista de libros de informtica; una lista de estudiantes y sus notas; un ndice con ttulos y contenido de los artculos publicados es una determinada revista, etc. En todos estos casos es necesario con frecuencia buscar un elemento en una lista. Una vez que se encuentra el elemento, la identificacin de su informacin correspondiente es un problema menor. Por consiguiente, nos centraremos en el proceso de bsqueda. Supongamos que se desea buscar el vector X [1]..X[n], que tiene componentes numricos, para ver si contiene o no un nmero dado T Si en vez de tratar sobre vectores se desea buscar informacin en un archivo, debe realizarse la bsqueda a partir de un determinado campo de informacin denominado campo clave. As, en el caso de los archivos de empleados de una empresa, el campo claves puede ser el nmero de DNI o los apellidos. La bsqueda por claves para localizar registros es, con frecuencia, una de las acciones que mayor consumo de tiempo conlleva y, por consiguiente, el modo en que los registros estn dispuestos y la eleccin del modo utilizado para la bsqueda pueden redundar en una diferencia sustancial en el rendimiento del programa. El programa de bsqueda cae naturalmente dentro de los dos casos tpicos ya tratados. Si extienden muchos registros, puede ser necesario almacenarlos en archivos de discos o cinta, externo a la memoria de la computadora. Este caso se denomina bsqueda externa. En el otro caso, los registros que se buscan se almacenan por completo dentro de la memoria de la computadora. Este caso se denomina bsqueda interna. En la prctica, en la bsqueda se refiere a la operacin de encontrar la posicin de un elemento entre un conjunto de elementos dados: lista, tabla o fichero. Ejemplos tpicos de bsqueda son localizar nombre y apellido de un alumno, localizar nmeros de telfono de una agenda, etc Existen diferentes algoritmos de bsqueda. El algoritmo elegido depende de la forma en que se encuentren organizados los datos. La operacin de bsqueda de un elemento N en un conjunto de elementos consiste en: Determinan si N pertenece al conjunto y, en caso, indicar su posicin en el, Determinar si N no perteneces al conjunto

Algoritmos

BUSQUEDA EN C++

Los mtodos ms usuales de bsqueda son: Bsqueda secuencial o lineal Bsqueda binaria Bsqueda por trasformacin de claves (hash)

Bsqueda secuencial Supongamos una lista de elementos almacenados en un vector (arraya unidimensional). El mtodo ms sencillo de buscar un elemento en un vector es explorar secuencialmente el vector o, dicho en otras palabras, recorre el vector desde el primer elemento al ltimo. Si se encuentra el elemento buscado, visualizar un mensaje similar a fin de bsqueda; en caso contrario, visualizar un mensaje similar a el elemento no existe en la lista. En otras palabras, la bsqueda secuencial compara cada elemento del vector con el valor deseado, hasta que este se encuentra o termina de leer el vector completo. La bsqueda secuencial no requiere ningn requisito por parte del vector y, por consiguiente, no necesitaba estar ordenado. El recorrido del vector se realiza normalmente con estructuras respectivas Ejemplo Si tiene un vector A que contiene n elementos numricos (N) >=1(A [1], A [2], A [3],, A[n]) y se desea buscar un elemento dado t. si el elemento t se encuentra, visualizar un mensaje el elemento encontrado y otro que diga posicin= Si existe n elementos, se requieran como media n/2 comparaciones para encontrar un determinado elemento. En el caso ms desfavorable se necesitara n comparaciones. Mtodo 1: Algoritmo busqueda_secuanecial_1 Inicio Leer (t) //recorrido del vector Desde i 1 hasta n hacer Si A[i] = t entonces Escribir (el elemento encontrado)

Algoritmos Escribir (en posicin, i) Fin_si Fin_desde Fin Mtodo 2: Algoritmo bsqueda_secuencial_2 Inicio Leer (t) I1 Mientras (A[i]) <> t) y (i =< n) hacer Ii+1

BUSQUEDA EN C++

//este bucle se detiene bien con A [1] = t o bien i >n Fin_mientras Si A [i] = t entonces //condicin de parada

Escribir (el elemento se ha encontrado en la posicin, i) Si_no //recorrido del vector terminado

Escribir (el numero no se encuentra en el vector) Fin_si Fin Este mtodo no es completamente satisfactorio, ya que si t no est en el vector A, i toma el valor n+1 y la comparacin A [i ] <> t Producir una referencia al elemento A[n+1], que presumiblemente no existe. Este problema se resuelve sustituyendo i =< n por i<n en la instruccin mientras, es decir, modificando la instruccin anterior mientras por Mientras (A[i] <> t) y (i < n) hacer Mtodo 3:

Algoritmos Algoritmo busqueda_secuencial_3 Inicio Leer (t) I1 Mientras (A[i] <> t) y (i < n) hacer Ii+1

BUSQUEDA EN C++

//este bucle se detiene cuando A [i] = t o i >= n Fin_mientras Si A[i] = t entonces Escribir (el numero deseado est presente y ocupa el lugar, i) Si_no Escribir (t, no existe en el vector) Fin_si Fin Mtodo 4: Algoritmo busqueda_secuecial_4 Inicio Llamar_a llenar (A) Leer (t) I1 Mientras i <=n hacer Si t = A[i] entonces Escribir (se encontr el elemento buscado en la posicin,1) Fin-si Ii+1

Algoritmos Fin _mientras Fin Busqueda secuencial con centinela

BUSQUEDA EN C++

Una manera muy eficaz de realizar una bsqueda secuencial consiste en modificar los algoritmos anteriores utilizando un elemento centinela. Este elemento se agrega al vector al final del mismo. El valor del elemento centinela es el del argumento. El propsito de este elemento centinela, A[n + |], es significar que la bsqueda siempre tendr existo. El elemento A[ n + 1] sirve como centinela y se le asigna el valor de t antes de iniciar la bsqueda. En cada paso se evita la comparacin de i con N y, por consiguiente, este algoritmo ser preferible a los mtodos anteriores, concretamente el mtodo 4. Si el ndice alcanzase el valor n + 1, supondra que el argumento no pertenece al vector original y, en consecuencia, la bsqueda no tiene xito

Mtodo 5: Algoritmo busqueda_secuencial_5 Inicio (t) I1 A[n + 1] t Mientras A[i] <> t hacer I i +1 Fin_mientras Si I = n + 1 entonces Escribir (no se ha encontrado elementos) Si_no Escribir (se ha encontrado el elementos) Fin_si Fin

Algoritmos

BUSQUEDA EN C++

Una variante del mtodo 5 es utilizar una variable lgica (interruptor o switch), que represente la existencia o no del elemento buscado. Localizar si el elemento t existe en una lista A [i], donde i vara desde 1 a n. En este ejemplo se trata de utilizar una variable lgica ENCONTRADO para indicar si existe o no el elemento de la lista

Mtodo 6: Algoritmo bsqueda_secuencial_6 Inicio Leer (t) I1 Encontrado falso Mientras (no ENCONTRADO) y (i =< n) hacer Si A[i] = t entonces ENCONTRADO VERDADERO Si_no Ii+1 Fin_si Fin_mientas Si ENCONTRADO entonces Escribir (el numero ocupa el lugar, i) Si _no Escribir (el nmero no est en el vector) Fin _ si Fin

Algoritmos

BUSQUEDA EN C++

NOTA. De todas las versiones anteriores, tal vez la ms adecuada sea la incluida en el mtodo 6. Entre otras razones, debido que el bucle mientras engloba las acciones que permiten explorar el vector bien hasta que t se encuentre bien cuando se alcance el final del vector Mtodo 6 Algoritmo Inicio Leer (t) I1 ENCONTRADO FALSO Mientras i =< n hacer Si A[ i ] entonces

ENCONTRADO VERDADERO Escribir (el numero ocupa el lugar ; i) Fin_si I i +1 Fin_mientras Si no (encontrado) entonces Escribir (el nmero no est en el vector ) Fin _ si Fin Mtodo 8 Algoritmo bsqueda_secuancial_8 Inicio ENCONTRADO FALSO I0

Algoritmos Leer (T) Repetir II+1 Si A[ i] = t entonces ENCONTRADO VERDADERO Fin_si Hasta _ que ENCONTRADO o (i = n) Fin

BUSQUEDA EN C++

Mtodo 9 Logaritmo bsqueda_secuencial_9 Inicio ENCONTRADO FALSO Leer (T) Desde I 1 hasta n hacer Si A[i] = t entonces Fin _ si Fin _ desde Si ENCONTRADO entonces Escribir (elemento encontrado) Si_no Escribir ( elemento no encontrado ) Fin _ si fin

Algoritmos

BUSQUEDA EN C++

Consideracin sobre la bsqueda lineal El mtodo de bsqueda lineal tiene el inconveniente del consumo excesivo de tiempo en la localizacin del elemento buscado. Cuando el elemento buscado no se encuentra en el vector, se verifican o comprueban sus n elementos. En los casos en que el elemento se encuentre en la lista, el nmero podr ser el primer, el ltimo o alguno comprendido entre ambos. Se puede suponer que el nmero medio de comprobaciones o comparaciones a realizar de ( n + 1)/2 (aproximadamente igual a la mitad de los elementos del vector). La bsqueda secuencial lineal n es el mtodo ms eficiente para vectores con un gran nmero de elementos. En estos casos, el mtodo ms idneo es el de bsqueda binaria, que presupone una ordenacin previa en los elementos del vector. Este caso suele ser muy utilizado en numerosas facetas de la vida diaria. Un ejemplo de ello es la bsqueda del numero abonado en una gua telefnica; normalmente no se busca el nombre en forma secuencial, sino que se busca en la primera o segunda mitad de la gua; una vez en esa mitad, se vuelve a tantear en una de sus dos submitades, as sucesivamente se repite el proceso hasta que se localiza para pgina correcta. Bsqueda Binaria En una bsqueda secuencial se comienza con el primer elemento del vector y se busca en el hasta que se encuentra el elemento deseado o se alcanza el final del vector. Aunque este puede ser un mtodo adecuado para pocos datos, se necesita una tcnica ms eficaz para conjuntos grandes de datos. Si el nmero de elementos del vector fuese grande, el algoritmo se bsqueda lineal se ralentizara de tiempo de un modo considerable .por ejemplo, si tuviramos que consultar un nombre en la gua telefnica de una gran ciudad como Madrid, con una cifra aproximada de un milln de abonados el tiempo de bsqueda ----segn el nombre--- se podra eternizar. Naturalmente, las personas que viven en esa gran ciudad nunca utilizaran el mtodo De bsqueda secuencial, sino un mtodo sino un mtodo que se basa en la divisin sucesiva del espacio ocupado por el vector en sucesivas mitades hasta encontrar el elemento buscado. Si los datos que se buscan estn clasificados en un determinado orden, el mtodo citado anteriormente se denomina bsqueda binaria. La bsqueda binaria utiliza un mtodo de <<divide y vencers>> para localizar el valor deseado. Con este mtodo se examina primero el elemento central de la lista; si este es el elemento buscado est en la primera o segunda mitad de la lista y, a continuacin, se repite este proceso, utilizando el elemento central de esa sub-lista. Supongamos la lista 1231 1473 1545 1834

Algoritmos 1892 1898 elemento central 1983 2005 2446 2685 3200

BUSQUEDA EN C++

Si est buscando el elemento 1983 se examina el nmero central 1898 en la sexta posicin ya que 1983 es mayor que 1898 se desprecia la primera sub-lista y nos centramos en la segunda: 1983 2005 2446 elemento central 2685 3200

Este nmero central de esta sub-lista es de 2446 y el buscador es 1983, menor que 2446; eliminamos las segunda sub-lista y nos queda 1983 2005 Como no hay termino central, elegimos el termino inmediatamente anterior al termino central 1983, que es el buscado. Se ha necesitado tres comparaciones, mientras que la bsqueda secuencial hubiese necesitado siete. La bsqueda binaria se utiliza en vectores ordenados y se basa en la constante divisin del espacio de bsqueda (recorrido del vector). Como se ha comentado, se comienzan comparando el elemento que se busca, no con el primer elemento, si no con el elemento central. Si el elemento buscado --t-- es menor que el elemento, entonces t deber estar en la mitad izquierda o inferior del vector; si es mayor que el valor central, deber estar en la mitad derecha o superior, u si es igual al valor central, se habr encontrado el elemento buscado. El funcionamiento de la bsqueda binaria en un vector de enteros para dos bsquedas: con xito (localizado el elemento) y sin xito (no encontrado el elemento) .

10

Algoritmos

BUSQUEDA EN C++

El proceso de bsqueda debe terminar normalmente conociendo si la bsqueda ha tenido xito ( se ha encontrado el elemento) o bien no ha tenido xito ( no se ha encontrado el elemento) y normalmente se deber devolver la posicin del elemento buscado dentro del vector Ejemplo Encontrar el algoritmo de bsqueda binaria para halla un elemento k en una lista de elementos X1, X2, , Xn previamente clasificados en orden ascendente El array o vector X se supone ordenado en orden creciente si los datos numricos, o alfabticamente si son caracteres. La variables bajo, central, alto indican los lmites inferior, central y superior del intervalo de bsqueda Algoritmo Inicio Leer (K) //inicializar variables Bajo 1 Alto N Central ent ((bajo + alto) / 2) Mientras (bajo =< alto) y (X[central] <> K) hacer Si k < X [central] entonces Alto central 1 Si _ no Bajo central + 1 Fin _si Central ent ((bajo + alto) /2) Fin_ mientas Si k = X [central] entonces Escribir (valor encontrado en, central) Si _no

11

Algoritmos Escribir (valor no encontrado) Fin _si Fin

BUSQUEDA EN C++

Ejemplo Se dispone de un vector tipo carcter NOMBRE clasificado en orden ascendente y de N elementos. Realizar el algoritmo que efectu la bsqueda de un nombre introducido por el usuario. La variable N indica cuantos elementos existen en el array. ENCONTRADO es una variable lgica que detecta si se ha localizado el nombre buscado. Algoritmo bsqueda_nombre // inicializar todas las variables necesarias NONBRE N ALTO BAJO CENTRAL X //array de caracteres //nmero de NOMBRES del array // puntero del extremo superior del intervalo // puntero del extremo inferior del intervalo // puntero al punto central del intervalo // nombre introducido por el usuario

ENCONTRADO // bandera o centinela

335 Inicio Leer (x) Bajo 1 Alto n Encontrado falso

12

Algoritmos

BUSQUEDA EN C++

Mientras (no encontrado) y (bajo =< alto) hacer Central ent ((bajo + alto) / 2) //verificar nombre central en este intervalo Si nombre [central] = X entonces ENCONTRADO VERDAD Si _no Si nombre [central] < X entonces Alto central 1 Si _ no Bajo central + 1 Fin_si Fin _si Si ENCONTRADO entonces Escribir (nombre encontrado) Si _ no Escribir (nombre no encontrado) Fin _si Fin

Anlisis de la bsqueda binaria La bsqueda binaria es un mtodo eficiente siempre que el vector este ordenado. En la prctica esto suele suceder. Pero no siempre. Por esta razn la bsqueda binaria exige una ordenacin previa del vector Para poder medir la velocidad de clculo del algoritmo de bsqueda binaria, se debern obtener el nmero de comparacin que realiza el algoritmo. Consideramos un vector de siete elementos (n=7). El numero 8 (n +1 =8) se debe dividir en tres mitades antes de que se alcance 1; es decir, se necesitan tres comparaciones

13

Algoritmos

BUSQUEDA EN C++

El medio matemtico de expresar estos nmeros es : 3= log2 (8) En general, para n elementos: K = log2 (n+1) Recuerde que el log2 (8) es el exponente al que debe elevarse 2 para obtener 8. Es decir, 3, ya q 2 a la 3 =8 Si n +1 es una potencia de 2, entonces log2 (n+1) ser un entero. Si n +1 no es una potencia de 2, el valor del logaritmo se redondea hasta el siguiente entero. Por ejemplo, si n es 12, entonces k ser a la 4, ya que log2(13) (que esta entre 3 y 4) se redondeara hasta 4 (2 a la 4 es 16) En general es el mejor de los casos se realizara una comparacin y, en el peor de los casos se realizaran log2 (n + 1) comparaciones. Como trmino medio, el nmero de comparaciones es: 1 +log2(n+1) 2 Esta frmula se puede reducir para el caso de que n sea grande a Log2(n+1) 2 Para poder efectuar una comparacin entre los mtodos de bsqueda lineal y bsqueda binaria, realicemos los clculos correspondientes para diferentes valores de n N = 100 En la bsqueda secuencial se necesitaran: 100 +1 2 50 comparaciones

En la bsqueda binaria log2 (100) = 6 .. Log2(100) = X 2 = 128< 100 donde 2X = 100Y X =6 7 comparaciones

N = 1000.000

en la bsqueda secuencial

14

Algoritmos

BUSQUEDA EN C++
1 000.000 +1 2 50.000 comparaciones

En la bsqueda binaria:

log2 (1000.000)=X

2x = 1000.000 donde X= 20 Y 2 a la 20 > 1000.000 20 comparaciones

Como se observa en los ejemplos anteriores, el tiempo de bsqueda es muy pequeo, aproximadamente siete comparaciones para 100 elementos y veinte para 1000.000 de elementos: (compruebe el lector que para 1.000 elementos se requieren un mximo de diez comparaciones.) la bsqueda binaria tiene, sin embargo, inconvenientes a resaltar: El vector debe estar ordenado y el almacenamiento de un vector ordenado suele plantear problemas en las inserciones y eliminaciones de elementos. ( en estos casos ser necesario utilizar listas enlazadas o arboles binarios.)

Bsqueda mediante transformaciones de claves (hashing) La bsqueda binaria proporciona un medio para reducir el tiempo requerido para buscar en una lista. Este mtodo, sin embargo, exige que los datos estn ordenados. Existen otros mtodos que puedan aumentar la velocidad de bsqueda en los que los datos no necesitan estar ordenados; este otro mtodo se conoce como trasformacin de claves (claves-direccin) o hashing. El mtodo de trasformacin de claves consiste en convertir la clave dad (numrica o alfanumrica) en una direccin (ndice) dentro de array. La correspondencia este las claves y la direccin en el medio de almacenamiento o en el array se establecen por una funcin de conversin (funcin hash). As, por ejemplo, en el caso de una lista de empleados (100) de una pequea empresa. Si cada uno de los cien empleados tiene un nmero de identificacin (clave)del 1 al 100, evidentemente puede existir una correspondencia directa entre la clave y la direccin definida en una vector o array de 100 elementos. Supongamos ahora que el campo calve de estos registros o elementos es el numero DNI o de la seguridad social, que contenga nuevos dgitos. Si se desea mantener en una array todo el rango posible de valores, se necesita 10 elevado a los 10 elementos en la tabla de almacenamiento, cantidad difcil de tener disponible en memoria central, aproximadamente 1.000.000.000 de registro o elementos. Si el vector o archivo solo tiene 100, 200 o 1.000 empleados, como hacer

15

Algoritmos

BUSQUEDA EN C++

para introducirlo en memoria por el campo clave DNI. Para hacer uso de la clave DNI como un ndice en la tabla de bsqueda, se necesita un medio para convertir el campo clave en una direccin o ndice ms pequeo. Los registros o elementos del campo clave no tienen por qu estar ordenados de acuerdo con los calores del campo clave, como estaban en la bsqueda binaria. por ejemplo, el registro del campo clave 345671234 estar almacenada en la tabla de trasformacin de claves (array) en una posicin determinada; por ejemplo, 75. la funcin de trasformacin de clave, H(k) convierte la clave (k) en una direccin (d). imaginemos que las claves fueran nombres o frases de hasta diecisis letras, que identifica a un conjunto de un millar de personas. Existen 26 elevado a la 16 combinaciones posibles de claves que se deben trasformar en 10 a la 3 direcciones o ndice posible. La funcin de H es, por consiguiente, evidentemente una funcin de paso o conversin de mltiples claves a direcciones. Dad una clave k, el primer paso en la operacin de bsqueda es calcular su ndice asociado d H(k) y el segundo paso----

Evidentemente necesario es verificar si o no el elemento con la clave k es identificado verdaderamente por h en el array t; es decir, para verificar si la clave T [h (k)] = k, se debe considerar dos preguntas: Qu clase de funcin H se utilizara? Cmo resolver la situacin de que H no produzca la posicin del elemento asociado?

la respuesta a la segunda cuestin es que se debe utilizar algn mtodo para producir una posicin alternativa, es decir, el ndice h, y si esta no es aun la posicin del elemento deseado, se produce un tercer ndice h, y as sucesivamente. El caso en el que una clave distinta de la deseada est en la posicin identificada se denomina colisin; la tarea de generacin de ndice alternativos se denomina tratamiento de colisiones.

Dos claves distintas producen la misma direccin, es decir, colisiones. La eleccin de una buena funcin de conversin exige un tratamiento idneo de colisiones, es decir, la reduccin del nmero de colisiones.

16

Algoritmos

BUSQUEDA EN C++

Mtodo de trasformacin de claves Existen numerosos mtodos de trasformacin de clave. Todos ellos tienen en comn la necesidad de convertir claves en direcciones. En esencia. La funcin de conversacin equivale a una caja negra que podramos llamar calculadora de direcciones. Cuando se desea localizar un elemento de clave X , el indicador de direcciones indicara en qu posicin del array estar situado el elemento Truncamiento Ignora pate de la clave y se utiliza la parte restante directamente como ndice (considerando campos no numricos y su cdigo numrico). Si las claves, por ejemplo, son enteros de ocho dgitos y la tabla de trasformacin tiene mil posiciones, entonces el primero, segundo y quinto dgitos desde la derecha pueden formar la funcin de conversin. Por ejemplo. 72588495 se convierte en 895. El truncamiento es un mtodo muy rpido, pero falla para distribuir las claves de modo uniforme. Plegamiento. La tcnica del plegamiento consiste en la particin de la clave en diferentes partes y la combinacin de las partes en un modo conveniente ( a menudo utilizando suma o multiplicacin) para obtener el ndice. La calve X se divide en varias partes, X1, X2, , Xn, donde cada parte, con la nica posible excepcin de la ltima parte, tiene el mismo nmero de dgitos que la direccin especifica. A continuacin, se suman todas las partes: H (x) = X1 + X2 + + Xn En esta operacin se desprecian los dgitos ms significativos que se obtengan de arrastre o acarreo.

Ejemplo Un entero de ocho dgitos se puede dividir en grupos de tres, tres y dos dgitos, los grupos se suman juntos u se trunca si es necesario para que estn en el rango adecuado de ndices. Por consiguientes, si la calve es: 62538194 Y el nmero de direcciones es 100, la funcin de conversin ser: 625 + 381 + 94 =1100

17

Algoritmos

BUSQUEDA EN C++

Que se truncara a 100 y que ser la direccin deseada

Ejemplo Los nmeros empleados campo clave de una empresa constan de cuatro dgitos y la direcciones reales son 100. Se desea calcular las direcciones correspondientes por el mtodo de plegamiento de los empleados 4205 8148 3355

H(4205) = 42 + 05 = 47 H(8148) = 81 + 48 = 129 H(3355) = 33 + 55 = 88

y se convierte en 29 (129 100), es decir, se ignora el acarreo 1

Si se desea afinar mas, se podra hacer la inversa de las partes pares y luego sumarlas. Aritmtica modular. Convertir la clave a un entero, dividido por el tamao del rango del ndice y tomar el resto como se resultado. La funcin de conversin utilizada es mod (modulo o resto de la divisin entera). H(x) = X mod m Donde m es el tamao del array con ndice de 0 a m1 los valores de la funcin direcciones(el resto) irn de 0 a m 1, ligeramente menor que el tamao del array. Al mejor eleccin de los mdulos son los nmero primos. Por ejemplo, en array de 1.000 elementos se puede elegir 997. Otros ejemplos son: 18 mod 6 19 mod 6 20 mod 6

Que proporciones unos restos de 0, 1 y 2, respectivamente. si se desea que las direcciones vayan de 0 hasta m, la funcin de conversin debe ser H(x) = X mod (m + 1)

Ejemplo Un vector T tiene cien posiciones, o...100. supongamos que las claves de bsqueda de los elementos de la tabla son enteros positivos (por ejemplo, nmero del DNI). una funcin de conversin h debe tomas un nmero arbitrario entero positivo x y convertirlo en un entero en el rango 0100, esto es, h es una funcin tal que para un entero es positivo X: H(X) = n donde n es entero en el rango 0100

18

Algoritmos

BUSQUEDA EN C++

El mtodo del modulo, tomando 101, ser: H(X) = X mod 101 Si se tiene el DNI numero 234661234, por ejemplo, se tendr la posicin 56: 234661234 mod 101 = 56 Ejemplo La clave de bsqueda es una cadena de caracteres tal como un nombre -- obtener las direcciones de conversin. El mtodo ms simple es asignar a cada carcter de la cadena un valor entero ( por ejemplo, A= 1, b = 2, ) y sumar los valores de los caracteres en la cadena. Al resultado se le aplica entonces el modulo 101, por ejemplo. si el nmero fuese JONAS, esta clave se convertirn en el entero 10 + 15 + 14+ 1 + 19 = 63 63 mod 101 = 63 Mitad del cuadro Este mtodo consiste en calcular el cuadrado de la clave X. la funcin de conversin se define como H(X) = C Donde c se obtiene eliminado dgitos a ambos extremos de X2, se deben utilizar la misma posiciones de X para todas las claves. Ejemplo Una empresa tiene ochenta y cada uno de ellos tiene un nmero de identificacin de cuatro dgitos y el conjunto de direccin de memoria varia en el rango de 0 a 100. Calcular las direcciones que se obtendr al aplicar funcin de conversin por la mitad del cuadrado de los nmeros empleados 4205 X X2 7148 3350 7148 51 093 904 3350 11 222 500

4205 17 682 025

Si elegimos, por ejemplo, el cuarto y quinto digito significativo, quedara H (X) 82 93 22

19

Algoritmos Colisiones

BUSQUEDA EN C++

La funcin de conversin h(x) no siempre proporciona valores distintos puede suceder que para dos claves diferentes X1 y X2 se obtenga la misma direccin. Esta situacin se denomina colisin y se deben encontrar mtodos para su correcta resolucin. los ejemplos vistos anteriormente de las calves DNI correspondientes al archivo de empleados, en el caso de cien posibles direcciones, si se considera el mtodo del mdulo en el caso de las claves, y se considera el numero primo 101 123445678 123445880 Proporcionaran las direcciones: H(123445678) = 123445678 mod 101 = 44 H(123445880) = 123445880 mod 101 = 44

Es decir, se tiene dos elementos en la misma posicin del vector o array, [44]. En terminologa de claves, se duce que las claves 123445678 y 123445880 han colisionado. el nico medio para evitar el problema de las colisiones totalmente es tener una posicin del array para cada posible nmero de DNI son las claves y el DNI se representa con nueve dgitos, se necesitara una posicin del array para cada entero en rango 000000000 a 999999999.evidentemente, sera necesario una gran cantidad de almacenamiento. En general, el nico mtodo para evitar colisiones totalmente es que el array sea lo bastante grandes para que cada posible el valor de la clave de bsqueda pueda tener su propia posicin. Ya que esto normalmente no es practico ni posible, se necesitara un medio para tratar o resolver las colisiones cuando sucedan.

Resolucin de colisiones consideramos el problema producido por una colisin. Supongamos que desea insertar un elemento con nmero nacional de identidad DNI 12345678, en una array T. se aplica la funcin de conversin del modulo y se determina que el nuevo elemento se situara en la posicin T [44]. Sin embargo, se observa T [44] ya contiene un elemento con DNI 123445779. La pregunta que se plantea inmediatamente es, Qu hacer con el nuevo elemento? Un mtodo comnmente utilizado para resolver una colisin es cambiar la estructura del array T de modo que pueda alojar ms de un elemento en la misma posicin. Se puede, por ejemplo, modificar T de modo que cada posicin T[i] sea por s misma un array capaz de contener N elementos. El problema, evidentemente, ser saber la magnitud de N. si N es muy pequeo, el problema de las colisiones aparecer cuando aparezcan N + 1 elementos. Una solucin mejor es permitir una lista enlazada o encadenada de elementos para formar a partir

20

Algoritmos

BUSQUEDA EN C++

de cada posicin del array. En este mtodo de resolucin de colisiones, conocido como encadenamiento, cada entrada T [i] es un puntero que apunta al elemento del principio de la lista de elementos de modo que la funcin de trasformacin de clave lo convierte en la posicin i

Intercalacin La intercalacin es el proceso de mezclar (intercalar) dos vectores ordenados y producir un nuevo vector ordenado. Consideremos los vectores (listas de elementos) ordenados A: 6 23 B: 5 22 34 26 27 39

El vector clasificado es: C: 5 6 22 23 24 26 27 39

La accin requera para solucionar el problema es muy difcil de visualiza. Un algoritmo sencillo puede ser: 1. Poner todos los valores del vector A en el vector C 2. Poner todos los valores del vector B en el vector C 3. Clasificar el vector c

Es decir, todos los valores se ponen en el vector C, con todos los valores de A seguidos por todos los valores de B. seguidamente, se clasifica el vector C. evidentemente, es una solucin correcta. Sin embargo, se ignora por completo el hecho de que los vectores A y B estn clasificados. Supongamos que los vectores A y B tienen M y N elementos. El vector C tendr, por tanto, M + N elementos El algoritmo comenzara seleccionando el ms pequeo de los dos elementos A y B, situndolo en C. para poder realizar las comparaciones sucesivas t la creacin del nuevo vector C, necesitaremos dos incides para los vectores A Y V. por ejemplo, i y j. entonces nos referimos al elemento i en la lista a y al elemento j en la lista B. los pasos generales del algoritmo son: Si elemento i de A es mejor que elemento j y b entonces Trasferido elemento i de A C Avanzar i (incrementar en 1) Si _no

21

Algoritmos Trasferir elementos j de B a C Avanzar J Fin _si

BUSQUEDA EN C++

Se necesita un ndice K que representa la posicin que se va rellenar en el vector en el vector C. // Estado inicial de los algoritmos i1 J1 K0 Mientras (i <= M) y (J <= n) hacer //seleccionar siguiente elemento de A o B y aadir a C K k +1 //incrementar K Si A [i] < B[j] entonces C [k] A [I] Ii+1 Si _no C[k] B[J] J j +1 Fin_si Fin_ mientras Si los vectores tienen elementos diferentes, el algoritmo anterior no requiere seguir haciendo comparaciones cuando el vector ms pequeo se termine de situar en C. la operacin siguiente deber copiar en C los elementos que restan del vector ms grande. As, por ejemplo, supongamos A=6 B=5 23 22 24 26 27 39 i=4 j=3

22

Algoritmos C=5 6 22 23

BUSQUEDA EN C++
24 k=5

Todos los elementos del vector A se ha relacionado y situado en el vector C. el vector B contiene los elementos no seleccionados y que deben ser copiados, en orden, al final del vector C. en general, ser necesario decidir cul de los vectores A o B tienen elementos no seleccionados a continuacin ejecutar las asignaciones necesarias El algoritmo de copia de los elementos restantes es: Si i < = M entonces Desde r i hasta M hacer Kk+1 C [K] B[r] Fin_ desde Si _no Desde r j hasta N hacer k k +1 C [K] B[r] Fin _ desde Fin _si El algoritmo total resultante de la intercalacin de dos vectores A y B ordenados en uno C es: Algoritmo intercalacin Inicio leer ( A, B) // A, B vectores de M y N elementos i1 j1 k 0 Mientras (i <= M) y ( j < = N) hacer //seleccionar siguiente elemento de A o B y aadirlo a C k k +1

23

Algoritmos Si A[i] < B [J] entices C[k] A[i] ii+1 Si _no C[K] B [J] j j + 1 Fin _si fin _ mientras //copiar el vector restante si i <= M entonces desde r i hasta N hacer k k +1 C[k] A[r] fin _ desde si _no desde r j hasta N hacer kk+1 C[k] B[r] fin_ desde fin _si escribir (c) //vector clasificado fin

BUSQUEDA EN C++

24

Algoritmos Bsqueda de cadenas

BUSQUEDA EN C++

Uno de los mtodos ms eficientes en la bsqueda de cadenas dentro de un texto es el algoritmo boyer moore. La implementacin bsica de este mtodo construye una tabla delta que se utilizara en la toma de decisiones durante la bsqueda de una sub-cadena. Dicha tabla contiene un nmero de entradas igual al nmero de caracteres del cdigo que se est utilizando. Por ejemplo si se est utilizando el cdigo de caracteres ASCII la tabla ser de 256 entradas. Cada entrada contiene el valor delta asociado con el carcter que representa. Por ejemplo el valor delta asociado con A estar en la entrada 65 y el valor delta asociado con el espacio en blanco, en la entrada 32. El valor delta para un carcter, es la posicin de la ocurrencia ms a la derecha de ese carcter respecto a la posicin final en la cadena bsqueda. Las entradas correspondientes a los caracteres que no pertenecen a las cadena a buscar, tienen un valor igual a la longitud de esta cadena. Por lo tanto para definir una la tabla delta para una determinada subcadena a buscar, construimos una matriz con todos sus elementos iniciados a la longitud de dicha cadena y luego, asignamos el valor delta para cada carcter de la subcadena, as: For ( i= 0; i< longitud_cadena_patron; i++) Delta [cadena_patron [i]]=longitude_cadena_patron i -1 ; En el algoritmo de boyer y moore la comparacin se realiza de derecha a izquierda empezando desde el principio del texto. Es decir, se empieza comparando el ultimo carcter de la cadena que se busca con el correspondiente carcter en el texto donde su busca; si los caracteres no coinciden, la cadena que se busca se desplaza hacia la derecha un numero de caracteres igual al calor indicado por la entrada en la tabla delta correspondiente al carcter del texto que no coincide. Si el carcter no aparece en la cadena que se busca, su calor delta en la longitud de la cadena que se busca. Veamos un ejemplo. Suponga que se desea buscar la cadena cien el texto ms vale un ya que cine despus se har. La bsqueda comienza as: Texto: ms vale un ya que cien despus har Cadena a busca: cien El funcionamiento del algoritmo puede comprenderse mejor sitiado la cadena a buscar paralela al texto. La comparacin es de derecha a izquierda; por lo tanto, se compara el ltimo carcter en la cadena a buscar (n) con el carcter que justamente encima en el texto (espacio). Como n es distinto de espacio la cadena que se busca debe desplazarse a la derecha un numero de caracteres igual al valor indicado por la entrada de en la tabla delta que corresponde al carcter del texto que no coincide. para la cadena cien

25

Algoritmos Delta *c+= 3 Delta *i+= 2 Delta *e+ =1 Delta *n+ = 0

BUSQUEDA EN C++

El resto de entradas valen 4 (longitud de la cadena). Segn esto, la cadena que se busca se desplaza cuatro posiciones a la derecha (el espacio en blanco no aparece en la cadena que se busca) Texto: ms vale un ya que cine despus se har

Cadena a buscar : cien Ahora n no coincide con e; luego la cadena se desplaza una posicin a la derecha (e tiene un valor asociado de uno) Texto: ms vale un ya que cine despus se har

Cadena a buscar: cien n no coincide con espacio, se desplaza la cadena cuatro posiciones a la derecha. Texto: ms vale un ya que cine despus se har Cadena a buscar: cien n no coincide con Y; se desplaza la cadena cuatro posiciones a la derecha. Texto: ms vale un ya que cine despus se har Cadena a buscar: cien n no coincide con u; se desplaza la cadena cuatro posiciones a la derecha. Texto: ms vale un ya que cine despus se har Cadena a buscar: cien n no coincide con i; se desplaza la cadena dos posiciones a la derecha. Texto: ms vale un ya que cine despus se har Cadena a buscar: cien Todos los caracteres de una cadena coinciden con los correspondientes caracteres en el texto. Para encontrar la cadena se han necesitado solo 7 + 3 comparaciones ( 7 hasta que se dio la

26

Algoritmos

BUSQUEDA EN C++

coincidencia del caracteres n; mas 3 para verificar que coincidan los 3 caracteres restantes). El algoritmo directo habra realizado 20 + 3 comparaciones, que en el peor de los casos, serian i* longcadbuscar, donde i es la posicin ms a la izquierda de la primera ocurrencia de la cadena a buscar en el texto ( 20 en el ejemplo anterior, suponiendo que la primera posicin es la 1) y logcadbuscar es la longitud de la cadena a buscar ( 4 en el ejemplo anterior). En el cabio el algoritmo boyer y more ampliara k+(i+longcadbuscar) comparaciones, donde k<1. Comprar la cadena con un carcter que ella no contiene. Cuando el carcter no coincidente en el texto, est presente en la cadena, el valor delta para ese carcter alinea la ocurrencia ms a la derecha de ese carcter en la cadena, con el carcter el texto A continuacin se muestra el cdigo correspondiente al algoritmo Boyer y moore. La funcin buscarcadena es la que se realiza el proceso descrito. Esta funcin devuelve la posicin de la cadena en el texto 0 -1 si la cadena no se encuentra( la primera posicin) Int buscarcadena (char *texto, char *cadena) //algoritmo de boyer y moore //buscar una cadena en un texto. Intj, longtex = strlen (texto) //construie la tabla delta Int delta [256]; Int i, longcad = strlen(cadena); // iniciar la tabla delta for (I = 0; I < 256; i++) delta [i] = longcad; //asignar valores a la tabla for (i =0; i < longcad; i++) delta [cadena[i]] = long cad I -1;

27

También podría gustarte