Está en la página 1de 14

Clase 6 : Enfrentamiento de Archivos

(fusión, mezcla o apareo)


Es un proceso por el cual 2 o más archivos, ordenados por el mismo campo de
secuencia (clave primaria o secundaria), se enfrentan registro a registro para
alguna tarea específica, obteniéndose como resultado listados y/o archivos.

AE1 AE2 Arch

ArchAct
Enfrentamiento

Altas
-- - - - - AS
----- Bajas ArchAct

Modificaciones
ArchAct
Mediante el proceso de enfrentamiento ABM se realiza el mantenimiento de un
archivo, que contempla:
  ALTAS: proceso que permite incorporar nuevos registros en un archivo
  BAJAS: proceso que permite eliminar registros de un archivo
 MODIFICACIONES: proceso que permite modificar la información almacenada en
registros de un archivo (salvo la clave)

Se desarrolla un ejemplo con los datos de los ejemplares de una biblioteca, grabados
en un archivo biblioteca
#COD. de LIBRO {campo de secuencia, clave primaria}
#CANTIDAD
#DESCRIPCION
Por otro lado se tienen los archivos:
compras, almacena los datos de los títulos adquiridos
(mismo diseño y orden de biblioteca)

eliminar, almacena los códigos de libro que se desean eliminar del archivo biblioteca

Proceso de altas y modificaciones utiliza los archivos biblioteca y compras 


Se enfrentan registro a registro los archivos biblioteca y compras, incorporándose
los títulos nuevos y actualizándose, por reposición, la cantidad de los títulos
existentes. Los datos actualizados son grabados en un tercer archivo actualizado.
Proceso de altas y modificaciones utiliza los archivos biblioteca y compras
Archivo biblioteca
Código Cantidad Descripcion

AAB2 6 xxxxxxxxxx

BZU7 0 xxxxxxxxxx Archivo compras


JUT5 20 xxxxxxxxxx Código Cantidad Descripcion

MKO9 8 xxxxxxxxxx ABH5 12 xxxxxxxxxx

PTR3 5 xxxxxxxxxx BZU7 10 ---------------

RHB5 3 xxxxxxxxxx LJY6 9 xxxxxxxxxx

TBM2 1 xxxxxxxxxx PTR3 5 ---------------

ZZZZ -- --------------- ZZZZ -- ---------------

Altas-Modificaciones

Biblioteca Compras Archivo Actualizado


Código Cantidad Descripcion
AAB2 6 xxxxxxxxxx
ABH5 12 xxxxxxxxxx Alta
BZU7 10 xxxxxxxxxx Modificación

JUT5 20 xxxxxxxxxx
Altas-Modificaciones
LJY6 9 xxxxxxxxxx Alta
MKO9 8 xxxxxxxxxx

PTR3 10 xxxxxxxxxx Modificación


RHB5 3 xxxxxxxxxx
Actualizado TBM2 1 xxxxxxxxxx
ZZZZ -- ---------------
El proceso de fusión de dos archivos se asemeja al de intercalación de dos
arreglos ordenados, donde se compara un elemento de cada uno y el de menor
valor es copiado a un tercero, incrementandose el índice del arreglo del cual
provino. Esto se repite hasta que uno o ambos arreglos finalicen. En el primer caso
los elementos del arreglo que no terminó serán procesados en su totalidad.
Intercalar dos archivos requiere comparar el campo de secuencia de dos registros,
uno de cada archivo, el de clave menor será grabado en un archivo de salida y
avanza leyendo el archivo del cual provino. Esto se repite hasta que uno o ambos
archivos alcancen el final. En el primer caso los registros del archivo que no finalizó
deben ser procesado en su totalidad.
Mientras (! FinArchivo (a1) && ! FinArchivo(a2)) hacer

Para simplificar el enfrentamiento y procesar dentro de un único ciclo la totalidad


de los registros de ambos archivos, se graba al final de cada uno un registro
"centinela" con un valor de clave mayor a todas. De esta forma al finalizar un
archivo no se detiene el ciclo. El archivo que finaliza primero deja en memoria su
registro centinela con clave mayor a todas las pendientes de proceso en el otro
archivo, dando "paso" a éstos hasta agotarlos (siempre se procesa el registro con
clave menor y se avanza en el archivo asociado).
El ciclo finaliza cuando ambos archivos alcanzan el final y sus registros
centinelas están en memoria.
Mientras (! FinArchivo (a1) || ! FinArchivo(a2)) hacer
En el enfrentamiento las componentes de los dos archivos son del mismo tipo:
struct libro y ambos están ordenados por código (de libro) clave primaria

#include <stdio.h>
#include <string.h>
struct libro { Se define 1 solo struct para libro y compras

char codigo[5];
int cant;
char descripcion[25];
};

void main (void) { /*main altas y reposición*/


FILE *biblioteca, *compras, *actualizado;
struct libro rb, rc;
biblioteca = fopen("biblioteca.dat","rb");
compras = fopen("compras.dat", "rb");
// controlar existencia de ambos archivos de entrada
actualizado = fopen("actualizado.dat", "wb");
. . .
...
fread(&rb, sizeof(struct libro), 1, biblioteca); 3 posibilidades:
biblio < compras
fread(&rc, sizeof(struct libro), 1, compras);
biblio = compras
while(!feof(biblioteca) || !feof(compras)) biblio > compras
if(strcmp(rb.codigo, rc.codigo) < 0) { /*rb no se modifica*/
fwrite(&rb, sizeof(struct libro), 1, actualizado); Es importante determinar qué
fread(&rb, sizeof(struct libro), 1, biblioteca); significa cada una
} else
if(strcmp(rb.codigo, rc.codigo) > 0) { /*es un alta*/
fwrite(&rc, sizeof(struct libro), 1, actualizado);
fread(&rc, sizeof(struct libro), 1, compras);
} else { /*son iguales los códigos: es una modificación*/
rb.cant += rc.cant;
fwrite(&rb, sizeof(struct libro), 1, actualizado);
fread(&rb, sizeof(struct libro), 1, biblioteca);
fread(&rc, sizeof(struct libro), 1, compras);
}
fclose(biblioteca); fclose(compras); fclose( actualizado);
} // fin main
Proceso de bajas utiliza los archivos biblioteca y eliminar
El archivo eliminar tiene grabados los códigos de los libros a dar de baja, sus
componentes son de tipo cadena, clave primaria
Archivo biblioteca

código cantidad descripcion

AAB2 6 xxxxxxxxxx
Archivo eliminar
BZU7 0 xxxxxxxxxx
código
JUT5
20 xxxxxxxxxx
MKO9 BZU7
8 xxxxxxxxxx MKO9
PTR3 5 xxxxxxxxxx RR04

ZZZZ -- --------------- ZZZZ

Bajas

Archivo actualizado
código cantidad descripción

AAB2 6 xxxxxxxxxx
JUT5 20 xxxxxxxxxx
PTR3 5 xxxxxxxxxx
#include <stdio.h>
#include <string.h>
struct libro {
char codigo[5];
int cant;
char descripcion[25];
};

void main (void) { /* main – Bajas */


FILE *biblioteca, *bajas, *actualizado;
struct libro rb;
char codbaja[5];
biblioteca = fopen("biblioteca.dat","rb"); // controlar existencia archivo
bajas = fopen(“bajas.dat", "rb"); // controlar existencia archivo
actualizado = fopen("actualizado.dat", "wb");
fread(&rb, sizeof(struct libro), 1, biblioteca);
fread(codbaja, 5, 1, bajas);
while(!feof(biblioteca) || !feof(bajas))
if(strcmp(rb.codigo, codbaja)<0) { /* rb no se elimina, se graba en el actualizado*/
fwrite(&rb, sizeof(struct libro), 1, actualizado);
fread(&rb, sizeof(struct libro), 1, biblioteca);
} else
if(strcmp(rb.codigo, codbaja)>0) /* error, no existe el código a eliminar*/
fread(codbaja, 5, 1, bajas);
else { /* los códigos son iguales, no se graba el registro */
fread(&rb, sizeof(struct libro), 1, biblioteca);
fread(codbaja, 5, 1, bajas);
}
fclose(biblioteca); fclose(bajas); fclose( actualizado);
}
Proceso que a partir de dos archivos con componentes de distinto tipo genera un tercero
 Dados dos archivos, el primero datos que contiene información sobre alumnos y el segundo
examenes que contiene información sobre las materias aprobadas por los alumnos (hay más
de un registro por alumno).
Se pide enfrentarlos y obtener un tercer archivo alumnos que agrupe la información total de
cada alumno.

archivo datos archivo examenes


# matricula (campo de secuencia, clave # matricula (campo de secuencia,clave
primaria) secundaria)
# apellido # materia
# fecha (de ingreso) # nota

struct
char
dato {
matricula[6];
Enfrentamiento struct examen {
char apellido[25]; char matricula[6];
char fecha[8]; struct exa exam;
};
};
archivo alumnos
# matricula struct exa {
struct alumno { char materia[5];
struct dato dat;
# apellido int nota;
int cantmat; };
struct exa vecmat[30];
# fecha
};
#cantmat
materia nota
#vecmat
0 1
#include <stdio.h>
#include <string.h>

struct exa {
char materia[5];
int nota;
};

struct examen {
char matricula[6];
struct exa exam;
};

struct dato {
char matricula[6];
char apellido[25];
char fecha[8];
};

struct alumno{
struct dato dat;
int cantmat;
struct exa vecmat[30];
};
void main(){
FILE *datos, *examenes, *alumnos;
struct dato rd; struct examen re; struct alumno ra; int i;
datos = fopen("datos.dat", "rb"); examenes = fopen("examenes.dat","rb"); //ctrl existencia
alumnos = fopen("alumnos",“wb");
fread(&re, sizeof(struct examen), 1, examenes); fread(&rd, sizeof(struct dato), 1, datos);
while(!feof(datos) || !feof(examenes))
if (!strcmp(rd.matricula, re.matricula)){ /* alumnos con materias rendidas */
i = 0;
while( !strcmp(rd.matricula, re.matricula)) {
ra.vecmat[i] = re.exam; i++;
fread(&re, sizeof(struct examen), 1, examenes);
}
ra.cantmat = i; /* luego del ciclo el alumno rd.matricula no tiene mas materias*/
ra.dat = rd; /* termina de cargar el registro ra, rd está en memoria*/
fwrite(&ra, sizeof(struct alumno), 1, alumnos);
fread(&rd, sizeof(struct dato), 1, datos);
} else
if (strcmp(rd.matricula,re. matricula)<0) { /*alumnos que no rinden examenes*/
ra.dat = rd; ra.cantmat = 0;
fwrite(&ra, sizeof(struct alumno), 1, alumnos);
fread(&rd, sizeof(struct dato), 1, datos);
} else /* examen que no pertenece a ningún alumno*/
fread(&re, sizeof(struct examen), 1, examenes);
fclose(datos); fclose(examenes); fclose(alumnos);
}
ORDENACION DE ARCHIVOS (mediante partición y fusión) 

En el caso de que el tamaño del archivo no permita su ordenación interna (leerlo


sobre un arreglo y ordenarlo en memoria, grabándolo finalmente sobre el archivo
original) se realiza la clasificación externa que requiere mayor tiempo de ejecución
(operaciones de lectura/escritura)

También puede realizarse una combinación de clasificación externa e interna,


aprovechando al máximo el espacio de memoria.

A continuación se describen dos métodos de clasificación externa que utilizan


archivos auxiliares.
1- Clasificación por mezcla directa
El método consiste en realizar sobre los datos del archivo una sucesión de particiones
y fusiones que producen secuencias ordenadas de longitud creciente.
La primera partición genera secuencias de longitud 1, que fusionadas sobre el archivo
original produce secuencias ordenadas de longitud 2.
En la siguiente partición se duplica la longitud de la secuencia, en cada partición-
fusión la duplicación de la longitud termina en un momento superando longitud del
archivo, determinando de esta forma el final del proceso de ordenación.
 
Ejemplo:
Sea F un archivo cuyos campos de secuencia figuran a continuación (no se incluyen los
campos restantes). Se utilizan dos archivos auxiliares F1 y F2, con la misma
estructura de F para realizar las particiones y fusiones.
 F : 15, 18, 7, 75, 14, 13, 43, 40, 51, 93, 75, 26, 64, 27, 13

............................................

El proceso termina al detectarse que la longitud (16) de la próxima secuencia (para la


partición) es mayor o igual que la cantidad de registros del archivo (15).
2-Clasificación por mezcla equilibrada
Es una optimización del método anterior que consiste en realizar la partición tomando
secuencias ordenadas de máxima longitud posible y realizando la fusión de dichas
secuencias alternativamente sobre dos archivos. O sea que el proceso de partición
fusión es simultáneo.
Se utilizan tres archivos auxiliares junto al original, siendo dos de entrada y dos de
salida en forma alternativa para la realización del proceso de partición-fusión
simultánea.
 
Ejemplo:
Sea F el archivo a ordenar y F1, F2 y F3 los archivos auxiliares con la misma estructura
de F.
Al comienzo se realiza por única vez la partición del archivo original en dos archivos.
 
F : 15, 18, 7, 75, 14, 13, 43, 40, 51, 93, 75, 26, 64, 27, 13

..........................................

El proceso termina cuando la partición-fusión deriva todos los registros a uno de


los archivos de salida, quedando el otro vacío.

También podría gustarte