52
1 Diego Gutiérrez Tema 22. Mezcla binaria de ficheros y vectores ordenados

Tema 22. Mezcla binaria de ficheros y vectores ordenadosgiga.cps.unizar.es/~diegog/ficheros/teaching/22.Mezcla.pdf · ordenadospara obtener un tercer fichero secuencial que almacene

Embed Size (px)

Citation preview

1Diego Gutiérrez

Tema 22. Mezcla binaria de ficheros y vectores ordenados

3Diego Gutiérrez

Recorrido simultáneo de dos ficheros

Ejemplo: Comparación de dos ficheros secuenciales.

Dados dos ficheros de datos de tipo tpFichero, parámetros del procedimiento, devolver a través de un tercer parámetro un valor lógico cierto si y sólo si los contenidos de ambos ficheros son idénticos.

Para ello es necesario que ambos ficheros tengan el mismo número de datos almacenados y que sus elementos homólogos sean iguales.

4Diego Gutiérrez

algoritmo sonIguales (ES f,g:tpFichero; ES loSon:booleano){ Pre: ---

Post: El parámetro “loSon” toma un valor “cierto” si y sólo los ficheros “f” y “g”almacenan secuencias idénticas de datos }

variablesdatoF,datoG: tpD;iguales: booleano;

principioiniciarLectura(f); iniciarLectura(g);{ Resolución del problema para dos secuencias vacías }iguales:= cierto;mientrasQue ¬finFichero(f) Y ¬finFichero(g) Y iguales hacer{ Compara los siguientes elementos de “f” y ”g” y actualiza la solución del problema

(valor de “iguales”) }leer(f,datoF); leer(g,datoG);iguales:= (datoF=datoG);

finMQloSon:= (iguales Y finFichero(f) Y finFichero(g));

Fin.

5Diego Gutiérrez

Gestión

6Diego Gutiérrez

Mezcla de dos ficheros secuenciales ordenados

Mezcla de los datos almacenados en dos ficheros secuenciales ordenados para obtener un tercer fichero secuencial que almacene una secuencia de datos, también ordenados, que integre los datos almacenados en los dos primeros ficheros y sólo éstos.

7Diego Gutiérrez

La principal dificultad del algoritmo a diseñar radica en la forma de acceso a los datos de los dos ficheros a mezclar:

Estos deben ser leídos y almacenados temporalmente en dos variables que han sido denominadas dato1 y dato2.

El proceso de mezcla se desarrolla comparando los valores de estas dos variables hasta que se alcanza el final de uno de los dos ficheros.

En ese momento no hay que olvidar que además, de los datos que restan de ser leídos en el otro fichero, quedan también por ser añadidos al fichero “f” los datos almacenados temporalmente en las variables dato1 y dato2.

8Diego Gutiérrez

9Diego Gutiérrez

dato1

dato2

10Diego Gutiérrez

dato1

dato2

11Diego Gutiérrez

dato1

dato2

12Diego Gutiérrez

dato1

dato2

13Diego Gutiérrez

dato1

dato2

14Diego Gutiérrez

dato1

dato2

15Diego Gutiérrez

dato1

dato2

16Diego Gutiérrez

dato1

dato2

17Diego Gutiérrez

dato1

dato2

18Diego Gutiérrez

dato1

dato2

19Diego Gutiérrez

dato1

dato2

20Diego Gutiérrez

dato1

dato2

21Diego Gutiérrez

dato1

dato2

22Diego Gutiérrez

dato1

dato2

Se alcanza el final de f2

23Diego Gutiérrez

dato1

dato2

Se comparan los valores de dato1 y dato2(igual que antes). Una vez escrito dato2…

24Diego Gutiérrez

dato1

…se copia el resto del fichero que aún no ha terminado

25Diego Gutiérrez

El algoritmo realiza la mezcla en dos etapas:

En la primera itera copiando en el fichero f los datos correspondientes de los otros dos ficheros f1 y f2 hasta llegar al final de al menos uno de los dos

En cada iteración se toma un dato de cada uno de estos ficheros como candidato a ser copiado en f. Se copia el que presenta un menor valor de su “medida” (según el criterio de comparación)

En la segunda etapa se continúa el proceso de comparación y copia hasta copiar el último dato de uno de los ficheros. Se procede a continuación a copiar en f los datos restantes que aún no han sido copiados del otro fichero.

26Diego Gutiérrez

algoritmo mezclarFicheros (ES f1,f2,f: tpFichero){ Pre: Los datos almacenados en “f1” y en “f2” están ordenados en sentido creciente

según “≤”Post: “f” es un fichero cuyos datos están ordenados en sentido creciente según “≤” y

son el resultado de mezclar todos los datos almacenados en los ficheros “f1” y “f2” }variablesdato1,dato2: tpD;

27Diego Gutiérrez

Si hay datos, se lee un dato de cada fichero

28Diego Gutiérrez

Si algún fichero no tiene datos, se copia el otro

29Diego Gutiérrez

principio { de mezclarFicheros }iniciarLectura(f1); iniciarLectura(f2); iniciarEscritura(f);si ¬finFichero(f1) entonces { el fichero “f1” contiene, al menos, un dato }

leer(f1,dato1);si ¬finFichero(f2) entonces { el fichero “f2” contiene, al menos, un dato }

leer(f2,dato2);

si_no { el fichero “f2” no almacena ningún dato }escribir(f,dato1); copiarResto(f1,f);

finSisi_no { el fichero “f1” no almacena ningún dato }copiarResto(f2,f);

finSifin

Instrucciones de mezcla

30Diego Gutiérrez

Mientras queden datos en ambos ficheros,leemos, escribimos, avanzamos

31Diego Gutiérrez

…mientrasQue ¬finfichero(f1) Y ¬finFichero(f2) hacer

si dato1≤dato2 entonces escribir(f,dato1); leer(f1,dato1);si_no escribir(f,dato2); leer(f2,dato2);

finSifinMQ…

En la primera itera copiando en el fichero f los datos correspondientes de los otros dos ficheros f1 y f2 hasta llegar al final de al menos uno de los dos

En cada iteración se toma un dato de cada uno de estos ficheros como candidato a ser copiado en f. Se copia el que presenta un menor valor de su “medida” (según el criterio de comparación)

32Diego Gutiérrez

Si ha terminado f1, comparo dato a dato como antes hasta escribir dato1, y copioel resto de f2

33Diego Gutiérrez

…si finFichero(f1) entonces { Leídos todos los datos de “f1” }

mientrasQue dato1>dato2 Y ¬finFichero(f2) hacerescribir(f,dato2); leer(f2,dato2);

finMQsi dato1≤dato2 entonces

escribir(f,dato1); escribir(f,dato2);copiarResto(f2,f);

si_no { Leídos todos los datos de “f2” }escribir(f,dato2); escribir(f,dato1);

finSi…

En la segunda etapa se continúa el proceso de comparación y copia hasta copiar el último dato de uno de los ficheros. Se procede a continuación a copiar en f los datos restantes que aún no han sido copiados del otro fichero.

34Diego Gutiérrez

Si ha terminado f2, comparo dato a dato hasta escribir dato2, y copio el resto de f1

35Diego Gutiérrez

…si_no { Leídos todos los datos de “f2” }

mientrasQue dato2>dato1 Y ¬finFichero(f1) hacerescribir(f,dato1); leer(f1,dato1);

finMQsi dato2≤dato1 entonces

escribir(f,dato2); escribir(f,dato1);copiarResto(f1,f);

si_no { Leídos todos los datos de “f1” }escribir(f,dato1); escribir(f,dato2);

finSi…

En la segunda etapa se continúa el proceso de comparación y copia hasta copiar el último dato de uno de los ficheros. Se procede a continuación a copiar en f los datos restantes que aún no han sido copiados del otro fichero.

36Diego Gutiérrez

algoritmo copiarResto(ES origen,destino: tpFichero){ Pre: ---Post: Han sido copiados en “destino” los elementos que estaban pendientes de ser

leídos del fichero “origen” }variables

dato: tpD;principio { de copiarResto }

mientrasQue ¬finFichero(origen) hacerleer(origen,dato); escribir(destino,dato);

finMQfin

37Diego Gutiérrez

38Diego Gutiérrez

Mezcla de estructuras de datos indexadas:

Copiar ordenadamente (mezclar) en una tabla T dos conjuntos de datos almacenados en dos tablas ordenadas T1 y T2. Los datos a mezclar son los almacenados en las tablas T1[1..n1]y T2[1..n2] y el resultado de su mezcla debe quedar almacenado en la tabla T[1..n1+n2]T, T1 y T2 son de tipo tpTabla definidas como:

constantesn = ... ; { Dimensión de las tablas }

tipostpÍndice = 1..n; { Índices de las tablas }tpTabla = tabla[tpÍndice] de tpDato;

39Diego Gutiérrez

40Diego Gutiérrez

De nuevo, el algoritmo realiza la mezcla en dos etapas:

En la primera itera hasta haber copiado en la tabla T todos los datos de una cualquiera de las dos tablas T1 y T2. En cada iteración se toma un dato de cada una de éstas tablas como candidato a ser copiado en la tabla T, y se copia el que presenta un menor valor de su “medida” (según el criterio de comparación)

En la segunda etapa se procede a copiar en T los datos que aún no han sido copiados de la tabla que no fue copiada en su totalidad durante la etapa anterior.

41Diego Gutiérrez

algoritmo mezclarTablasOrdenadas (E T1,T2:tpTabla; E n1,n2: entero; ES T: tpTabla){ Pre/ Post}

algoritmo copiarResto ( )tipos

tpÍndiceAmpliado=0..n;variables

índiceT,índiceT1,índiceT2:tpÍndiceAmpliado;principio

índiceT1:=0; índiceT2:=0; índiceT:=0;mientrasQue (índiceT1<n1) Y (índiceT2<n2) hacer

índiceT:=índiceT+1;si medida(T1[índiceT1+1])≤medida(T2[índiceT2+1])

entonces índiceT1:=índiceT1+1;T[índiceT]:=T1[índiceT1];

si_no índiceT2:=índiceT2+1;T[índiceT]:=T2[índiceT2];

finSifinMQsi índiceT1<n1 entonces

copiarResto(T1,T,índiceT1+1,n1,índiceT+1);si_no

copiarResto(T2,T,índiceT2+1,n2,índiceT+1);finSi

Fin.

42Diego Gutiérrez

algoritmo mezclarTablasOrdenadas (E T1,T2:tpTabla; E n1,n2: entero; ES T: tpTabla){ Pre/ Post}

algoritmo copiarResto ( )tipos

tpÍndiceAmpliado=0..n;variables

índiceT,índiceT1,índiceT2:tpÍndiceAmpliado;principio

índiceT1:=0; índiceT2:=0; índiceT:=0;mientrasQue (índiceT1<n1) Y (índiceT2<n2) hacer

índiceT:=índiceT+1;si medida(T1[índiceT1+1])≤medida(T2[índiceT2+1])

entonces índiceT1:=índiceT1+1;T[índiceT]:=T1[índiceT1];

si_no índiceT2:=índiceT2+1;T[índiceT]:=T2[índiceT2];

finSifinMQsi índiceT1<n1 entonces

copiarResto(T1,T,índiceT1+1,n1,índiceT+1);si_no

copiarResto(T2,T,índiceT2+1,n2,índiceT+1);finSi

Fin.

Pre: Las subtablas T1[1..n1] y T2[1..n2] estánordenadas en sentido no decreciente (“≤”)según el valor de la “medida” de sus datosy se satisface que (n1+n2)≤n

Post: La subtabla T[1..n1+n2] almacena, ordenados en sentido no decreciente (“≤”) según el valor de su “medida”, todos los datos de lassubtablas T1[1..n1] y T2[1..n2] }

Pre: Las subtablas T1[1..n1] y T2[1..n2] estánordenadas en sentido no decreciente (“≤”)según el valor de la “medida” de sus datosy se satisface que (n1+n2)≤n

Post: La subtabla T[1..n1+n2] almacena, ordenados en sentido no decreciente (“≤”) según el valor de su “medida”, todos los datos de lassubtablas T1[1..n1] y T2[1..n2] }

43Diego Gutiérrez

algoritmo mezclarTablasOrdenadas (E T1,T2:tpTabla; E n1,n2: entero; ES T: tpTabla){ Pre/ Post}

algoritmo copiarResto ( )tipos

tpÍndiceAmpliado=0..n;variables

índiceT,índiceT1,índiceT2:tpÍndiceAmpliado;principio

índiceT1:=0; índiceT2:=0; índiceT:=0;mientrasQue (índiceT1<n1) Y (índiceT2<n2) hacer

índiceT:=índiceT+1;si medida(T1[índiceT1+1])≤medida(T2[índiceT2+1])

entonces índiceT1:=índiceT1+1;T[índiceT]:=T1[índiceT1];

si_no índiceT2:=índiceT2+1;T[índiceT]:=T2[índiceT2];

finSifinMQsi índiceT1<n1 entonces

copiarResto(T1,T,índiceT1+1,n1,índiceT+1);si_no

copiarResto(T2,T,índiceT2+1,n2,índiceT+1);finSi

Fin.

44Diego Gutiérrez

algoritmo mezclarTablasOrdenadas (E T1,T2:tpTabla; E n1,n2: entero; ES T: tpTabla){ Pre/ Post}

algoritmo copiarResto ( )tipos

tpÍndiceAmpliado=0..n;variables

índiceT,índiceT1,índiceT2:tpÍndiceAmpliado;principio

índiceT1:=0; índiceT2:=0; índiceT:=0;mientrasQue (índiceT1<n1) Y (índiceT2<n2) hacer

índiceT:=índiceT+1;si medida(T1[índiceT1+1])≤medida(T2[índiceT2+1])

entonces índiceT1:=índiceT1+1;T[índiceT]:=T1[índiceT1];

si_no índiceT2:=índiceT2+1;T[índiceT]:=T2[índiceT2];

finSifinMQsi índiceT1<n1 entonces

copiarResto(T1,T,índiceT1+1,n1,índiceT+1);si_no

copiarResto(T2,T,índiceT2+1,n2,índiceT+1);finSi

Fin.

Comenzamos a mezclar por los índices inferioresComenzamos a mezclar por los índices inferiores

45Diego Gutiérrez

algoritmo mezclarTablasOrdenadas (E T1,T2:tpTabla; E n1,n2: entero; ES T: tpTabla){ Pre/ Post}

algoritmo copiarResto ( )tipos

tpÍndiceAmpliado=0..n;variables

índiceT,índiceT1,índiceT2:tpÍndiceAmpliado;principio

índiceT1:=0; índiceT2:=0; índiceT:=0;mientrasQue (índiceT1<n1) Y (índiceT2<n2) hacer

índiceT:=índiceT+1;si medida(T1[índiceT1+1])≤medida(T2[índiceT2+1])

entonces índiceT1:=índiceT1+1;T[índiceT]:=T1[índiceT1];

si_no índiceT2:=índiceT2+1;T[índiceT]:=T2[índiceT2];

finSifinMQsi índiceT1<n1 entonces

copiarResto(T1,T,índiceT1+1,n1,índiceT+1);si_no

copiarResto(T2,T,índiceT2+1,n2,índiceT+1);finSi

Fin.

Se mezclan las dos tablas T1 y T2 hasta agotar los datos en una de ellasSe mezclan las dos tablas T1 y T2 hasta agotar los datos en una de ellas

46Diego Gutiérrez

algoritmo mezclarTablasOrdenadas (E T1,T2:tpTabla; E n1,n2: entero; ES T: tpTabla){ Pre/ Post}

algoritmo copiarResto ( )tipos

tpÍndiceAmpliado=0..n;variables

índiceT,índiceT1,índiceT2:tpÍndiceAmpliado;principio

índiceT1:=0; índiceT2:=0; índiceT:=0;mientrasQue (índiceT1<n1) Y (índiceT2<n2) hacer

índiceT:=índiceT+1;si medida(T1[índiceT1+1])≤medida(T2[índiceT2+1])

entonces índiceT1:=índiceT1+1;T[índiceT]:=T1[índiceT1];

si_no índiceT2:=índiceT2+1;T[índiceT]:=T2[índiceT2];

finSifinMQsi índiceT1<n1 entonces

copiarResto(T1,T,índiceT1+1,n1,índiceT+1);si_no

copiarResto(T2,T,índiceT2+1,n2,índiceT+1);finSi

Fin.

Copiamos un nuevo dato en T[indice]…Copiamos un nuevo dato en T[indice]…

47Diego Gutiérrez

algoritmo mezclarTablasOrdenadas (E T1,T2:tpTabla; E n1,n2: entero; ES T: tpTabla){ Pre/ Post}

algoritmo copiarResto ( )tipos

tpÍndiceAmpliado=0..n;variables

índiceT,índiceT1,índiceT2:tpÍndiceAmpliado;principio

índiceT1:=0; índiceT2:=0; índiceT:=0;mientrasQue (índiceT1<n1) Y (índiceT2<n2) hacer

índiceT:=índiceT+1;si medida(T1[índiceT1+1])≤medida(T2[índiceT2+1])

entonces índiceT1:=índiceT1+1;T[índiceT]:=T1[índiceT1];

si_no índiceT2:=índiceT2+1;T[índiceT]:=T2[índiceT2];

finSifinMQsi índiceT1<n1 entonces

copiarResto(T1,T,índiceT1+1,n1,índiceT+1);si_no

copiarResto(T2,T,índiceT2+1,n2,índiceT+1);finSi

Fin.

Copiamos un nuevo dato en T[indice]……desde T1…Copiamos un nuevo dato en T[indice]……desde T1…

48Diego Gutiérrez

algoritmo mezclarTablasOrdenadas (E T1,T2:tpTabla; E n1,n2: entero; ES T: tpTabla){ Pre/ Post}

algoritmo copiarResto ( )tipos

tpÍndiceAmpliado=0..n;variables

índiceT,índiceT1,índiceT2:tpÍndiceAmpliado;principio

índiceT1:=0; índiceT2:=0; índiceT:=0;mientrasQue (índiceT1<n1) Y (índiceT2<n2) hacer

índiceT:=índiceT+1;si medida(T1[índiceT1+1])≤medida(T2[índiceT2+1])

entonces índiceT1:=índiceT1+1;T[índiceT]:=T1[índiceT1];

si_no índiceT2:=índiceT2+1;T[índiceT]:=T2[índiceT2];

finSifinMQsi índiceT1<n1 entonces

copiarResto(T1,T,índiceT1+1,n1,índiceT+1);si_no

copiarResto(T2,T,índiceT2+1,n2,índiceT+1);finSi

Fin.

Copiamos un nuevo dato en T[indice]……desde T1……o desde T2

Copiamos un nuevo dato en T[indice]……desde T1……o desde T2

49Diego Gutiérrez

algoritmo mezclarTablasOrdenadas (E T1,T2:tpTabla; E n1,n2: entero; ES T: tpTabla){ Pre/ Post}

algoritmo copiarResto ( )tipos

tpÍndiceAmpliado=0..n;variables

índiceT,índiceT1,índiceT2:tpÍndiceAmpliado;principio

índiceT1:=0; índiceT2:=0; índiceT:=0;mientrasQue (índiceT1<n1) Y (índiceT2<n2) hacer

índiceT:=índiceT+1;si medida(T1[índiceT1+1])≤medida(T2[índiceT2+1])

entonces índiceT1:=índiceT1+1;T[índiceT]:=T1[índiceT1];

si_no índiceT2:=índiceT2+1;T[índiceT]:=T2[índiceT2];

finSifinMQsi índiceT1<n1 entonces

copiarResto(T1,T,índiceT1+1,n1,índiceT+1);si_no

copiarResto(T2,T,índiceT2+1,n2,índiceT+1);finSi

Fin.

Discriminamos qué tabla (T1, T2) no ha sido copiado aún íntegramente en TDiscriminamos qué tabla (T1, T2) no ha sido copiado aún íntegramente en T

50Diego Gutiérrez

algoritmo mezclarTablasOrdenadas (E T1,T2:tpTabla; E n1,n2: entero; ES T: tpTabla){ Pre/ Post}

algoritmo copiarResto ( )tipos

tpÍndiceAmpliado=0..n;variables

índiceT,índiceT1,índiceT2:tpÍndiceAmpliado;principio

índiceT1:=0; índiceT2:=0; índiceT:=0;mientrasQue (índiceT1<n1) Y (índiceT2<n2) hacer

índiceT:=índiceT+1;si medida(T1[índiceT1+1])≤medida(T2[índiceT2+1])

entonces índiceT1:=índiceT1+1;T[índiceT]:=T1[índiceT1];

si_no índiceT2:=índiceT2+1;T[índiceT]:=T2[índiceT2];

finSifinMQsi índiceT1<n1 entonces

copiarResto(T1,T,índiceT1+1,n1,índiceT+1);si_no

copiarResto(T2,T,índiceT2+1,n2,índiceT+1);finSi

Fin.

Discriminamos qué tabla (T1, T2) no ha sido copiado aún íntegramente en T

Quedan datos por copiar en T1…

Discriminamos qué tabla (T1, T2) no ha sido copiado aún íntegramente en T

Quedan datos por copiar en T1…

51Diego Gutiérrez

algoritmo mezclarTablasOrdenadas (E T1,T2:tpTabla; E n1,n2: entero; ES T: tpTabla){ Pre/ Post}

algoritmo copiarResto ( )tipos

tpÍndiceAmpliado=0..n;variables

índiceT,índiceT1,índiceT2:tpÍndiceAmpliado;principio

índiceT1:=0; índiceT2:=0; índiceT:=0;mientrasQue (índiceT1<n1) Y (índiceT2<n2) hacer

índiceT:=índiceT+1;si medida(T1[índiceT1+1])≤medida(T2[índiceT2+1])

entonces índiceT1:=índiceT1+1;T[índiceT]:=T1[índiceT1];

si_no índiceT2:=índiceT2+1;T[índiceT]:=T2[índiceT2];

finSifinMQsi índiceT1<n1 entonces

copiarResto(T1,T,índiceT1+1,n1,índiceT+1);si_no

copiarResto(T2,T,índiceT2+1,n2,índiceT+1);finSi

Fin.

Discriminamos qué tabla (T1, T2) no ha sido copiado aún íntegramente en T

Quedan datos por copiar en T1……o quedan datos por copiar en T2

Discriminamos qué tabla (T1, T2) no ha sido copiado aún íntegramente en T

Quedan datos por copiar en T1……o quedan datos por copiar en T2

52Diego Gutiérrez

algoritmo mezclarTablasOrdenadas (E T1,T2:tpTabla; E n1,n2: entero; ES T: tpTabla){ Pre/ Post}

algoritmo copiarResto ( )tipos

tpÍndiceAmpliado=0..n;variables

índiceT,índiceT1,índiceT2:tpÍndiceAmpliado;principio

índiceT1:=0; índiceT2:=0; índiceT:=0;mientrasQue (índiceT1<n1) Y (índiceT2<n2) hacer

índiceT:=índiceT+1;si medida(T1[índiceT1+1])≤medida(T2[índiceT2+1])

entonces índiceT1:=índiceT1+1;T[índiceT]:=T1[índiceT1];

si_no índiceT2:=índiceT2+1;T[índiceT]:=T2[índiceT2];

finSifinMQsi índiceT1<n1 entonces

copiarResto(T1,T,índiceT1+1,n1,índiceT+1);si_no

copiarResto(T2,T,índiceT2+1,n2,índiceT+1);finSi

Fin.

algoritmo copiarResto (E tablaOriginal:tpTabla; ES tablaCopia:tpTabla; E primerÍndice,ultimoÍndice:tpÍndice; E índiceCopia:tpÍndice)

{ Pre: ---Post: Copiados en “tablaCopia”, a partir de su índice “índiceCopia”,

los datos de “tablaOriginal” cuyos índices están comprendidos entre “primerÍndice” y “ultimoÍndice” }variables

índice:tpÍndice;principio

para índice desde primerÍndice hasta ultimoÍndice hacertablaCopia[índiceCopia+índice-primerÍndice]:=

tablaOriginal[índice];finPara

Fin.

algoritmo copiarResto (E tablaOriginal:tpTabla; ES tablaCopia:tpTabla; E primerÍndice,ultimoÍndice:tpÍndice; E índiceCopia:tpÍndice)

{ Pre: ---Post: Copiados en “tablaCopia”, a partir de su índice “índiceCopia”,

los datos de “tablaOriginal” cuyos índices están comprendidos entre “primerÍndice” y “ultimoÍndice” }variables

índice:tpÍndice;principio

para índice desde primerÍndice hasta ultimoÍndice hacertablaCopia[índiceCopia+índice-primerÍndice]:=

tablaOriginal[índice];finPara

Fin.

53Diego Gutiérrez

Conclusiones: