Resolución de Problemas y Algoritmos Segundo cuatrimestre 2015 Clase 8: Bucles anidados y Archivos Dr. Sergio A. Gómez http://cs.uns.edu.ar/~sag Departamento de Ciencias e Ingeniería de la Computación Universidad Nacional del Sur Bahía Blanca, Argentina Primitivas de Pascal para archivos secuenciales • Assign(F, N): vincula F (manejador interno) con N (nombre real en el disco). • Rewrite(F): crea un archivo nuevo (sobre-escribe si ya existe otro con ese nombre, el cual se pierde). • Write(F, e): en un archivo creado con rewrite, escribe el valor de “e” a continuación del último elem. de F. • Close(F): cierra el archivo vinculado al handler F. • Reset(F): abre un archivo existente para leer, y queda preparado para leer el primer elemento. • Read(F, e): lee un elemento del archivo F, copia el valor leido en “e” y queda preparado para leer el siguiente elemento (si existe). • Eof(F) (end of file): retorna TRUE si se llegó al final de un archivo y FALSE en caso contrario. Resolución de Problemas y Algoritmos Dr. Alejandro J. García 2 • Problema: Dado un archivo de enteros ordenados en forma creciente llamado c:\archivo2.dat, se desea buscar un entero ingresado por teclado. • Algoritmo: Recorrer al archivo secuencialmente hasta: 1. Encontrar el elemento x buscado: 3 5 6 14 26 F 2 60 80 94 EOF Si x es 14, recorro hasta el 14 y corto la búsqueda con éxito 2. Pasarse del lugar donde debería estar el elemento x: F 2 3 5 6 14 26 60 80 94 EOF Si x es 18, cuando encuentro el 26, corto la búsqueda sin éxito. 3. Llegar al fin de archivo: F 2 3 5 6 14 26 60 80 94 EOF Si x es 98, cuando encuentro el EOF, corto la búsqueda sin éxito. Resolución de Problemas y Algoritmos - Dr. Sergio A. Gómez 3 program BuscarOrdenado; const nombre_archivo = 'c:\archivo2.dat'; var f : file of integer; e, x : integer; encontre , me_pase : boolean; begin Write( 'Ingrese elemento a buscar: ' ); ReadLn(x); Assign( f, nombre_archivo ); Reset( f ); encontre := false; me_pase := false; while not Eof( f ) and not encontre and not me_pase do begin Read( f, e ); if e = x then encontre := true else if e > x then me_pase := true end; Close( f ); if encontre then WriteLn( x, ' pertenece al archivo.' ) else WriteLn( x, ' no pertenece al archivo.' ); End. Resolución de Problemas y Algoritmos - Dr. Sergio A. Gómez 4 Problema: Dado un archivo de números enteros c:\archivo1.dat y un entero n leído de teclado, se desean eliminar todas las apariciones de n del archivo. Algoritmo: 1) Leer n de teclado. 2) Recorrer el archivo y grabar cada número distinto de n en otro archivo temporal (e.g. c:\archivo1.tmp). 3) Luego, copiar el contenido del archivo temporal sobre archivo1.dat. 4) Finalmente, eliminar el archivo temporal. 1) n 3 2 3 5 3 14 3 60 3 14 60 94 EOF 94 EOF archivo1.dat 2) 3) 2 5 archivo1.tmp Nota: Usaremos la primitiva Erase( f ) que elimina un file f. Resolución de Problemas y Algoritmos - Dr. Sergio A. Gómez 5 Algoritmo: 1. Leer n de teclado 2. Generar archivo temporal con componentes distintas a n. 3. Copiar archivo temporal sobre archivo. 4. Eliminar archivo temporal program EliminarApariciones; const nombre_archivo = 'c:\archivo1.dat'; nombre_temporal = 'c:\archivo1.tmp'; Var f, f_tmp : file of integer; n, dato : integer; begin { 1 - Leer n de teclado. } Write( 'Ingrese valor a eliminar del archivo: ' ); ReadLn( n ); Resolución de Problemas y Algoritmos - Dr. Sergio A. Gómez 6 Algoritmo: 1. Leer n de teclado 2. Generar archivo temporal con componentes distintas a n. 3. Copiar archivo temporal sobre archivo. 4. Eliminar archivo temporal { 2. Generar archivo temporal con componentes distintas a n. } Assign( f, nombre_archivo ); Assign( f_tmp, nombre_temporal ); Reset( f ); Rewrite( f_tmp ); while not Eof( f ) do begin Read( f, dato ); WriteLn( 'Procesando ', dato ); if dato <> n then Write( f_tmp, dato ); end; Close( f ); Resolución de Problemas y Algoritmos - Dr. Close( f_tmp ); Sergio A. Gómez 7 Algoritmo: 1. Leer n de teclado 2. Generar archivo temporal con componentes distintas a n. 3. Copiar archivo temporal sobre archivo. 4. Eliminar archivo temporal { 3. Copiar temporal sobre archivo. } Rewrite( f ); Reset( f_tmp ); while not Eof( f_tmp ) do begin Read( f_tmp, dato ); Write( f, dato ); WriteLn( 'Guardando ', dato ); end; Close( f ); Close( f_tmp ); Resolución de Problemas y Algoritmos - Dr. Sergio A. Gómez 8 Algoritmo: 1. Leer n de teclado 2. Generar archivo temporal con componentes distintas a n. 3. Copiar archivo temporal sobre archivo. 4. Eliminar archivo temporal { 4. Eliminar archivo temporal. } WriteLn( 'Eliminando temporal' ); Erase( f_tmp ); WriteLn( 'Enter...' ); ReadLn; end. Ejercicio: Dado un archivo archivo_r.dat de caracteres, leer dos caracteres C y D por teclado y reemplazar todas las apariciones de C en el archivo por D. Resolución de Problemas y Algoritmos - Dr. Sergio A. Gómez 9 Problema: Dado un archivo de enteros llamado c:\archivo1.dat, contar las apariciones de 1 seguido de 4. Algoritmo: cont_apariciones 0 Anterior 9 { Cualquier valor distinto a 1. } Para cada elemento x del archivo hacer obtener componente actual si anterior = 1 y actual = 4 entonces incrementar cont_apariciones anterior actual Mostrar cont_apariciones Resolución de Problemas y Algoritmos - Dr. Sergio A. Gómez 10si program ContarUnoCuatro; Const dummy = 9; Var arch : file of integer; actual, anterior : integer; cont_apariciones : integer; Begin cont_apariciones := 0; anterior := dummy; Assign( arch, ‘c:\archivo1.dat’ ); Reset( arch ); while not Eof( arch ) do begin Read( arch, actual ); if (anterior = 1) and (actual = 4 ) then cont_apariciones := cont_apariciones + 1; anterior := actual; end; Close( arch ); WriteLn( ‘El 1 seguido del 4 aparece ‘, cont_apariciones, ‘ veces’ ); End. Resolución de Problemas y Algoritmos - Dr. Sergio A. Gómez 11 Bucles anidados: Ejemplo • Problema: Realizar un programa para calcular el valor 2 4 de la expresión: (i + 3 j ) ∑∑ • Algoritmo: i =1 j =1 Suma 0 Para i desde 1 hasta n hacer para j desde 1 hasta m hacer suma suma + i + 3j Program SumaTodo; Var suma : real; Begin suma := 0.0; for i := 1 to 2 do for j := 1 to 4 do suma := suma + i + 3*j; Write(‘Suma vale: ‘, suma : 10 : 3 ) End. Resolución de Problemas y Algoritmos - Dr. Sergio A. Gómez 12 Problema: Supongamos un calendario de 12 meses y cada mes de exactamente 30 días. Se desea procesar un archivo datos.dat conteniendo 360 valores correspondientes a las lluvias en mm de cada día de cada mes de un año. Se quiere obtener el día de la máxima lluvia del año, así como el promedio por mes. Algoritmo: Maximo -1; Enlazar archivo con datos.dat; Abrir archivo para lect. Para cada mes m entre 1 y 12 hacer suma 0.0 para cada día d entre 1 y 30 hacer recuperar dato x del archivo; suma suma + x si x > maximo entonces maximo x; dia_max d; mes_max m finsi Implementar en Pascal finpara promedio suma / 30; mostrar promedio, mes Finpara Resolución de Problemas y Algoritmos - Dr. Mostrar maximo, dia_max, mes_max; Cerrar archivo Sergio A. Gómez 13 Problema: Supongamos un archivo datos.dat conteniendo séxtuplas de enteros donde cada uno corresponde a muestras de día, mes, año, cantidad en mm de lluvia, temperaturas máxima y mínima tomadas por un científico. Se quiere obtener la fecha en la que llovió el máximo, el día más frío y el día más cálido junto con los datos con la cantidad de lluvía y las temperaturas correspondientes. Ejemplo: 1 3 2013 34 45 2 …. Quiere decir que el 1/3/2013 llovieron 34mm y la máxima fueron 45° y la mínima 2°. Resolución de Problemas y Algoritmos - Dr. Sergio A. Gómez 14