Documentos de Académico
Documentos de Profesional
Documentos de Cultura
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
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
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
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
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++
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
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
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
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
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
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
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