P. 1
lenguaje algoritmico 5

lenguaje algoritmico 5

|Views: 1.359|Likes:
Publicado poranon-68902

More info:

Published by: anon-68902 on Jul 02, 2008
Copyright:Attribution Non-commercial

Availability:

Read on Scribd mobile: iPhone, iPad and Android.
download as DOC, PDF, TXT or read online from Scribd
See more
See less

06/16/2009

pdf

text

original

TUPLAS Introducción a las Estructuras de Datos Definición de nuevos tipos de datos Manipulación de tuplas Vectores de tuplas Lectura/escritura

de Tuplas desde teclado y fichero Funciones y acciones que devuelven tuplas Ejercicio completo Ejercicios propuestos Introducción a las Estructuras de Datos Hasta ahora hemos centrado básicamente nuestro estudio en una forma adecuada de algoritmizar problemas, o lo que es lo mismo, de encontrar algoritmos de solución para ciertos problemas del mundo real. Para conseguirlo nos hemos basado en: • • • Utilización eficiente de las estructuras de control básicas: asignación, secuencia, alternativa e iteración Dividir el problema en subproblemas más fáciles de solucionar, construyendo programas según un diseño descendente o top-down (diseño modular) Reutilización de algoritmos mediante la utilización de librerías de componentes ya desarrollados y probados

Sin embargo, existe otro gran area de conocimiento que hemos tratado con poca profundidad hasta ahora y es la de utilizar tipos de datos “avanzados”. En nuestro estudio hemos introducido los tipos básicos (predefinidos) como el entero, el real, el carácter, o el lógico, y con posterioridad hemos visto como agrupar datos del mismo tipo (homogeneos) en “almacenes” como son las tablas1. A la vez hemos estudiado que los datos pueden proceder del dispositivo de entrada estandar (el teclado) o bien pueden proceder de un almacenamiento permanente en disco (un fichero2). Asimismo la escritura de resultados puede realizarse en pantalla o bien en ficheros. En programación existe una igualdad que debe intentar cumplirse: PROGRAMA = ALGORITMO + ESTRUCTURAS DE DATOS De tal forma que los programas desarrollados con estructuras de datos adecuadas, resultan de mayor nivel y legibilidad, redundando esto en su costo de mantenimiento, de actualización y de desarrollo. Como estructuras de datos (EDs) se conoce a todo aquello que sirva para almacenar de forma organizada distintas informaciones que se deban manipular en los algoritmos. Existen distintos tipos de EDs como son las listas, colas, árboles, grafos, etc., que se salen fuera de nuestros objetivos. Sin embargo vamos a estudiar como crear nuevos
1

Comúnmente en programación se llama vectores o arrays a las tablas unidimensionales, y matrices a las bidimensionales. Además, los arrays de caracteres se denominan cadenas o strings. 2 Los ficheros que hemos estado utilizando han sido de texto (que contienen caracteres ASCII o de otro código), pero también pueden utilizarse ficheros binarios, cuya manipulación es más eficiente y compacta, pero que no pueden ser abiertos con un editor de texto.

tipos de datos a partir de los ya existentes, de forma que las nuevas variables de estos nuevos tipos puedan contener información diversa (hetereogenea). A estos tipos de datos los llamaremos estructuras, registros o tuplas. Ejemplo: si queremos almacenar algunas de las distintas informaciones que caracterizan a una persona, podremos crear una tupla que contenga un espacio para almacenar su nombre, otro para su edad y otro para su teléfono (cada una de estas informaciones se denomina campo, y cada uno será del tipo adecuado a los datos que tenga que albergar):
Nombre: cadena Edad: entero Teléfono: cadena

Definición de nuevos tipos de datos Definiremos en lenguaje algorítmico los nuevos tipos de datos dentro del párrafo Utilizando, de forma que podremos utilizarlos en el fichero en el que se incluya3. Veamos un ejemplo concreto: Ejemplo: definición de un tipo de datos tupla para contener información relativa a una persona. Al nuevo tipo lo llamamos persona.
Utilizando Tipo Persona=tupla Nombre: cadena Edad: entero Telefono: cadena ftupla Ftipo

A partir de esta definición podemos crear variables de ese nuevo tipo, y por supuesto podemos dar valores a sus campos, para lo que utilizaremos el operador de selección de campo ( . ):
p, q: persona; p.nombre:= ”pepe” p.edad:= 23 p.telefono:= ”956662112”

Podemos asignar variables de tipo estructura directamente (por ejemplo, para dos hermanos gemelos):
q:=p q.nombre:= ”manolo”

Se pueden crear tipos aún más avanzados, a partir de los ya existentes:
3

Podemos hacerlo también de otra forma: crear un fichero independiente con los nuevos tipos de datos que queramos utilizar en nuestra aplicación en incluir éste posteriormente en todos aquellos archivos en los que se pretenda hacer uso de esos tipos.

Ejemplo: creación de un tipo tupla alumno, a partir del tipo persona (damos por hecho que cualquier alumno es una persona, y además tiene otras características)
Tipo Alumno=tupla Datos: persona Notas: tabla[50] de real Curso: entero ftupla Ftipo

De esta forma, podemos definir variables de este nuevo tipo y darle valores:
x,y: alumno x.curso:= 1 x.notas[0]:= 5.0 x.notas[1]:= 7.5 x.datos.nombre:= “carlos”

Manipulación de tuplas Aparte de dar valores individuales a los campos de una variable de tipo estructura, debemos estudiar por su importancia y amplia utilización la forma de crear tablas o vectores de tuplas y como rellenar éstas con informaciones procedentes ya sea de teclado o de fichero. Creación de vectores de tuplas De la misma manera que creabamos tablas de números reales o de enteros, es posible crear variables que sean tablas de registros. Por ejemplo:
lista_amigos: tabla[100] de persona lista_clase: tabla[400] de alumno

Con estas definiciones podemos hacer, por ejemplo, que “pepe” sea nuestro primer amigo:
lista_amigos[0]:=p // ya que “pepe” era la variable persona p

O podemos rellenar individualmente algún campo de alguno de nuestros amigos:
lista_amigos[1].nombre:= “alfonso”

Evidentemente sobre los vectores de tuplas se pueden utilizar los mismos mecanismos que sobre las tablas de enteros o reales que estabamos acostumbrados a manejar. Es decir, se pueden atacar de la misma forma (con los mismos esquemas) problemas de recorrido y de búsqueda. Veremos algunos ejemplos después del apartado siguiente.

Lectura/escritura de Tuplas desde teclado y fichero Directamente vamos a escribir una acción para leer una serie de informaciones desde el teclado y almacenar sus valores en un vector de registros. Como las tablas tienen una longitud finita, debemos controlar no pasarnos del límite de valores definidos (supongamos máximo4 100). Además el algoritmo devolverá el número de personas introducidas en el vector, es decir que el vector no tiene porqué rellenarse de forma completa. Como marca o persona final utilizaremos la persona cuyo nombre sea “fin”.
acción LeerTuplas (sal v:tabla[100] de persona, sal numero_personas: entero) var p: persona i: entero fvar i:=0 leer(p) mientras p.nombre < > “fin” y i < 100 // para no pasarnos del tamaño definido v[i]:=p i:=i+1 leer(p) // se puede leer( ) una estructura fmientras numero_personas:=i // devolvemos el número de personas que hay en el vector facción

En realidad, no hay demasiadas cosas nuevas, ya que la manipulación de vectores incompletos era un asunto que ya habíamos tratado con anterioridad. Ahora vamos a escribir una acción que rellene el vector de tuplas con los datos contenidos en un fichero de texto que tiene el formato siguiente:
Pepe Carlos … 23 24 956662112 956661221

accion LeerFicheroTuplas (ent nomfich: cadena, sal v:tabla[100] de persona, sal numero_personas: entero) var p: persona; i: entero f: fichero; e: lógico fvar AbrirFich(nomfich,”lectura”,f,e) si (no e) i:=0 mientras (no FinFich(f)) y i<100 LeerFich(f,p) v[i]:=p i:=i+1 fmientras numero_personas:=i sino numero_personas:=-1 // para controlar desde el exterior el error fsi CerrarFich(f) facción
4

Cuando utilicemos en nuestros programas vectores o matrices de cualquier tipo, es necesario que tengamos en cuenta que las dimensiones por defecto de memoria reservada para cada programa no son muy amplias con lo que el tamaño de las tablas no podrá rebasar un cierto valor dependiente de cada compilador y de algunas opciones de éste.

Para escribir en un fichero un vector incompleto de tuplas podemos hacer un recorrido del vector hasta el número de elementos que realmente contenga:
Acción EscribirFicheroTuplas (ent nomfich: cadena, ent v:tabla[100] de persona, ent numero_personas: entero) var i: entero f: fichero e: lógico fvar AbrirFich(nomfich,”escritura”,f,e) si e=FALSO para i:=0 hasta numero_personas-1 EscribirFich(f,v[i]) fpara fsi CerrarFich(f) facción

Ejemplo: recorrido de un vector de tuplas para encontrar la edad media de nuestros amigos almacenados en una tabla.
función EdadMedia (ent lista_amigos:tabla[100] de persona, ent numero_amigos: entero): real var I: entero edad_med: real fvar edad_med:=0.0 para i:=0 hasta numero_amigos-1 edad_med:=edad_med+lista_amigos[i].edad fpara retorna (edad_med/(real)numero_amigos) ffunción

Funciones y acciones que devuelven tuplas Se pueden desarrollar componentes que devuelvan tuplas individualmente. Veamos un ejemplo para encontrar el punto medio de un segmento definido por dos puntos P y Q. Antes de nada deberemos definir un nuevo tipo punto:
Tipo punto=tupla x,y: real ftupla Ftipo función PuntoMedio (ent p: punto, ent q: punto): punto var pm: punto fvar pm.x:= (p.x+q.x)/2.0 pm.y:= (p.y+q.y)/2.0 retorna pm; ffunción

De esta forma hemos conseguido que una función pueda devolver más de un valor (en este caso dos, ya que devolvemos una variable de tipo punto que contiene dos campos de tipo real5). Como acción tendría la siguiente implementación:
acción PuntoMedio (ent p: punto, ent q: punto, sal pm: punto) pm.x:= (p.x+q.x)/2.0 pm.y:= (p.y+q.y)/2.0 facción

Ejemplo: Buscar a qué amigo pertenece un teléfono que tenemos apuntado sin su nombre correspondiente.
función BuscarAmigo (ent lista_amigos:tabla[100] de persona, ent numero_amigos: entero, ent telefono_sin_nombre: cadena): persona var i: entero; persona_nula: persona; fvar persona_nula:={“”,-1,””} i:=0 mientras lista_amigos[i].telefono < > telefono_sin_nombre y i < numero_amigos i: = i+1 // se hace un recorrido hasta encontrarlo o terminar fmientras si i < > numero_amigos retorna lista_amigos[i] // una persona sino retorna persona_nula // para su control desde el exterior de esta función fsi ffunción

Ejercicio completo Supongamos que tenemos un fichero de texto en el que se encuentran almacenadas las informaciones relativas a una lista de personas, de tal forma que en cada fila del fichero hay un registro completo. Queremos almacenar todos los registros en un vector, buscar las personas que tengan una cierta edad (que se pedirá por teclado), y escribir esos registros en otro fichero.
Definiendo // definición de constantes N=100 Utilizando // definición de tipos Tipo Persona=tupla Nombre: cadena Edad: entero Telefono: cadena ftupla Ftipo

5

Hasta ahora sólo habiamos estudiado funciones que devuelven un valor.

// prototipos de acciones y/o funciones función LeerFicheroTuplas (ent nomfich: cadena, sal v:tabla[N] de persona): entero función BuscaEdad (ent v:tabla[N] de persona, ent num:entero, ent edad:entero, sal v_misma_edad:tabla[N] de persona): entero acción EscribirFicheroTuplas (ent nomfich: cadena, ent v:tabla[N] de persona, ent numero_personas: entero) Acción Principal var nomfich1,nomfich2: cadena lista, lista_misma_edad:tabla[N] de persona edad,num_personas, num_edad: entero fvar leer(nomfich1) num_personas:=LeerFicheroTuplas(nomfich1,lista) si num_personas < > -1 leer(edad) num_edad:=BuscaEdad(lista,num_personas,edad,lista_misma_edad) leer(nomfich2) EscribirFicheroTuplas(nomfich2,lista_misma_edad,num_edad) sino escribir(‘Error en la apertura del fichero de datos’) fsi escribir(‘Fin del programa’) facción

función LeerFicheroTuplas (ent nomfich: cadena, sal v:tabla[100] de persona): entero var p: persona i,num_personas: entero f: fichero e: lógico fvar AbrirFich(nomfich,”lectura”,f,e) si (no e) i:=0 mientras (no FinFich(f)) y i<100 LeerFich(f,p) v[i]:=p i:=i+1 fmientras numero_personas:=i sino numero_personas:=-1 // para controlar desde el exterior el error fsi CerrarFich(f) facción

acción EscribirFicheroTuplas (ent nomfich: cadena, ent v:tabla[100] de persona, ent numero_personas: entero) var i: entero f: fichero e: lógico fvar AbrirFich(nomfich,”escritura”,f,e) si e=FALSO para i:=0 hasta numero_personas-1 EscribirFich(f,v[i]) fpara fsi CerrarFich(f) facción función BuscaEdad (ent v:tabla[N] de persona, ent num:entero, ent edad:entero, sal v_misma_edad:tabla[N] de persona): entero var i,k: entero fvar para i:=0 hasta num-1 k:=0 si v[i].edad = edad v_misma_edad[k]:=v[i] k:=k+1 fsi fpara retorna k ffunción

Ejercicios
1. Realizar un programa en L. Algorítmico y C que permita leer dos números reales que representan los límites inferior y superior de un intervalo, un tercero que representa el número de puntos a considerar (no mayor de 100), y a partir de estos datos de entrada, calcule las ordenadas de todas las abcisas comprendidas entre el límite inferior y el superior sobre un círculo de radio r (que se deberá introducir también como entrada por teclado) centrado en el origen. • • Se deberá diseñar un tipo nuevo que se llame ordenada Se deberá construir un algoritmo independiente para calcular y devolver las ordenadas de un círculo y otro para encontrar un vector de ordenadas a partir de los límites del intervalo y el número de puntos deseado (este segundo algoritmo deberá utilizar el primero)

2.

Ejemplo de un programa que calcula las soluciones de una ecuación de 2º grado. (versión con devolución de una estructura, tupla o registro)

Solución Lenguaje Algorítmico: Utilizando Tipo raizdoble = tupla sol1: real sol2: real ftupla ftipo función sol_ec_2grado(ent a, b, c: real): raizdoble

acción principal var a2, a1, a0: real solucion: raizdoble fvar leer(a2, a1, a0) solucion:=sol_ec_2grado(a2, a1, a0) escribir(solucion) facción función sol_ec_2grado(ent a, b, c: real): raizdoble var r: raizdoble fvar r.sol1= (-b+raiz(b*b- 4.0*a*c)/(2.0*a) r.sol2= (-b-raiz(b*b- 4.0*a*c)/(2.0*a) retorna r; facción Lenguaje C
#include <stdio.h> #include <math.h> typedef struct{ float sol1; float sol2; }raizdoble; raizdoble sol_ec_2grado(float a, float b, float c); /************************************************************************/ /* Programa que calcula las soluciones de una ec. de 2 grado */ /* Funciones utilizadass: sol_ec_2_grado() */ /* Realizado por: Dpto LSI - Sección Algeciras */ /* Fecha de Creación: 31/03/1998 */ /* Revisión: --/--/-(Por: ------) */ /************************************************************************/ void main(void) { char cad[15]; float a2, a1, a0; raizdoble solucion; printf ("\nIntroduzca coeficiente a2:"); gets(cad); a2=atof(cad); printf ("\nIntroduzca coeficiente a1:"); gets(cad); a1=atof(cad); printf ("\nIntroduzca coeficiente a0:"); gets(cad); a0=atof(cad); solucion=sol_ec_2grado(a2, a1, a0); printf("\nLas soluciones son %f y %f", solucion.sol1, solucion.sol2); }

/************************************************************************/ /* Función que calcula las raices de una ecuación de segundo grado */ /* Entradas: tres valores reales (coeficientes de la ec.) */ /* Salidas: una estructura de tipo raizdoble */ /* Funciones utilizadas: --*/ /* Realizado por: Dpto LSI - Sección Algeciras */ /* Fecha de Creación: 31/03/1998 */ /* Revisión: --/--/-(Por: ------) */ /************************************************************************/ raizdoble sol_ec_2grado(float a, float b, float c) { raizdoble r; r.sol1= (-b+sqrt(b*b- 4*a*c))/(2*a); r.sol2= (-b-sqrt(b*b- 4*a*c))/(2*a); return r; }

3.

Realizar un programa en L. Algorítmico y C que lea un conjunto de 10 números enteros (como máximo) DESDE FICHERO (utilizando cadenas de caracteres y conversión a enteros) y calcule la media y la varianza (utilizando un solo algoritmo). Se deberán realizar dos versiones de este algoritmo, la primera que proporcione como salida dos valores reales independientes y la segunda que proporcione una estructura que contenga los valores deseados. Realizar un programa en L. Algorítmico y C que permita leer dos números reales que representan los límites inferior y superior de un intervalo, un tercero que representa el número de puntos a considerar (no mayor de 100), y a partir de estos datos de entrada, calcule las ordenadas de todas las abcisas comprendidas entre el límite inferior y el superior sobre un círculo de radio r (que se deberá introducir también como entrada por teclado) centrado en el origen, Y ESCRIBA ÉSTAS EN UN FICHERO DE SALIDA DE DATOS. • • Se deberá diseñar un tipo nuevo que se llame ordenada Se deberá construir un algoritmo independiente para calcular y devolver las ordenadas de un círculo y otro para encontrar un vector de ordenadas a partir de los límites del intervalo y el número de puntos deseado (este segundo algoritmo deberá utilizar el primero)

4.

5.

Ejemplo de un programa que lee un vector de registros (de personas) desde un fichero, se almacenan en un vector, se ordena por las edades de las personas y luego se escribe en un fichero de salida.

Lenguaje Algorítmico: Utilizando Tipo persona = tupla nombre: cadena edad: entero ftupla ftipo acción LeerFichero (ent nomfich: cadena; sal v:tabla [10] de persona; sal numitems : entero); acción EscribirFichero (ent nomfich: cadena; ent v:tabla [10] de persona; ent numitems : entero); acción OrdenarVector (ent numitems : entero; ent/sal v:tabla [10] de persona); acción principal var nomfichero_entrada: cadena; nomfichero_salida: cadena; numero_elementos: entero lista: tabla[10] de persona; fvar leer(nomfichero_entrada); LeerFichero(nomfichero_entrada,lista,numero_elementos); si numero_elementos <> -1 OrdenarVector(lista); leer(nomfichero_salida); EscribirFichero(nomfichero_salida,lista,numero_elementos); sino Escribir(“Lo siento, no se puedo abrir el fichero de datos.”); fsi facción acción LeerFichero (ent nomfich: cadena; sal v:tabla [10] de persona; sal numitems : entero) var p: persona; i: entero; f: fichero; e:lógico; fvar AbrirFich(nomfich,”lectura”,f,e); si e=FALSO i:=0; mientras (FinFich(f)=FALSO y i<10) LeerFich(f,p); v[i]:= p; i:=i+1; fmientras numitems:=i; CerrarFich(f); sino numitems:=-1; fsi facción

acción OrdenarVector(ent numitems:entero , ent/sal v: tabla[10] de persona) var i: entero; paux: persona; intercambio : lógico; fvar intercambio := verdadero; mientras intercambio=verdadero intercambio := falso i := 0; mientras i < numitems-1 si v[i+1].edad < v[i].edad paux := v[i]; v[i] := v[i+1]; v[i+1] := paux; intercambio := verdadero fsi i := i+1; fmientras fmientras facción acción EscribirFichero (ent nomfich: cadena; ent v:tabla [10] de persona; ent numitems : entero) var i: entero; f:fichero; e:lógico; fvar AbrirFich(nomfich,”escritura”,f,e); si e=FALSO para i:=0 hasta numitems-1 EscribirFich(f,v[i]); fpara CerrarFich (f); fsi facción Lenguaje C
#include <stdio.h> #include <string.h> typedef struct{ char nombre[40+1]; int edad; }persona; void LeerFichero (char nomfich[20+1], persona v[10], int *numitems); void OrdenarVector(int numitems, persona v[10]); void EscribirFichero (char nomfich[20+1], persona v[10], int numitems); void main(void) { char nomfichero_entrada[20+1]; char nomfichero_salida[20+1]; int numero_elementos; persona lista[10]; printf("\nIntroduzca el nombre del fichero de personas/edades"); gets(nomfichero_entrada);

LeerFichero(nomfichero_entrada,lista,&numero_elementos); if (numero_elementos!=-1) { OrdenarVector(numero_elementos, lista); printf("\nDatos ordenados"); printf("\nIntroduzca el nombre del fichero de salida"); gets(nomfichero_salida); EscribirFichero(nomfichero_salida,lista,numero_elementos); } else printf(“\nNo se pudo abrir el fichero de datos.”); } void LeerFichero (char nomfich[20+1], { FILE *S; persona p; int i; S= fopen (nomfich,"rt"); if (S==NULL) exit(1); i=0; while (!feof(S)) { fscanf(S,"%s%d\n",p.nombre, &p.edad); strcpy(v[i].nombre, p.nombre); v[i].edad = p.edad; i = i+1; } fclose(S); *numitems = i; } void OrdenarVector(int numitems, persona v[10]) { int i, intercambio; persona paux; intercambio = 1; while (intercambio == 1) { intercambio = 0; i = 0; while (i < numitems-1) { if (v[i+1].edad < v[i].edad) { paux.edad=v[i].edad; strcpy(paux.nombre, v[i].nombre); v[i].edad=v[i+1].edad; strcpy(v[i].nombre, v[i+1].nombre); v[i+1].edad=paux.edad; strcpy(v[i+1].nombre, paux.nombre); intercambio = 1; } i = i+1; } } } void EscribirFichero (char nomfich[20+1], int numitems) { FILE *S; int i; S = fopen (nomfich,"wt"); persona v[10], persona v[10], int *numitems)

if (S==NULL) exit(1); for(i=0;i<numitems;i++) fprintf(S,"%s %d\n",v[i].nombre,v[i].edad); fclose(S); }

6. • • •

Realizar en lenguaje algorítmico y en C un programa que resuelva el siguiente problema: Se dispone de un fichero de tuplas (x,y,z) que determina una figura en el espacio tridimensional. El tamaño máximo que el fichero podrá alcanzar será 100+M tuplas. Se dispone de otro fichero que contiene una matriz 3x3 de transformación de puntos en el espacio. Se desea obtener un fichero que contenga los puntos del fichero original transformados (según la matriz antes mencionada), y ordenados según su distancia al origen de coordenadas.

Nota: El alumno deberá crear los dos ficheros de entrada para las pruebas del programa. Solución Para resolver este problema: • se definirá un nuevo tipo de datos tupla (x,y,z) que llamaremos punto. • utilizaremos un vector de 100 elementos de tipo punto para almacenar las tuplas del fichero de entrada. • utilizaremos una matriz de 3x3 números para almacenar la matriz de transformación. • utilizaremos otro vector de 100 tuplas que contrendrá las tuplas resultado de la multiplicación de cada tupla original por la matriz de transformación, y que posteriormente será ordenado. La descomposición Top-Down del problema en subproblemas queda de la forma:

PRINCIPAL

LEER VECTOR DE PUNTOS

LEER MATRIZ DE TRANSFORMACIÓN

OBTENER VECTOR TRANSFORMADO

ORDENAR VECTOR

ESCRIBIR FICHERO DE SALIDA

LEER VECTOR DE PUNTOS: A partir de un nombre de fichero, carga las tuplas contenidas en un vector de tuplas, dando a la salida en número de tuplas cargadas. LEER MATRIZ DE TRANSFORMACIÓN: A partir de un nombre de fichero, carga los nueve números que contiene en una matriz de 3x3. OBTENER VECTOR TRANSFORMADO: A partir de un vector de tuplas, el número de tuplas a procesar y una matriz de transformación, multiplica cada tupla por la matriz, y almacena los resultados en un vector de tuplas transformadas. ORDENAR VECTOR: A partir de un vector de tuplas y el número de tuplas a procesar, ordena este vector con el criterio de la mínima distancia al origen. ESCRIBIR VECTOR DE SALIDA: A partir de un nombre de fichero de salida, de un vector de tuplas y el número de tuplas a procesar, las almacena en el fichero de salida.

Lenguaje Algorítmico Utilizando tipo tupla = punto x,y,z: real; ftupla ftipo función LeerVectorPuntos(ent nom: cadena, sal v: tabla[100] de punto):entero; función LeerMatriz(ent nom:cadena, sal m: tabla[3][3] de real):lógico; acción ObtenerTransformado(ent v: tabla [100] de punto, num_tuplas:entero, m: tabla[3][3] de real, sal vt: tabla [100] de punto); acción OrdenarVector(ent numitems:entero, sal v: tabla[100] de punto); acción EscribirVector(ent nom: cadena, v: tabla [100] de punto,num_tuplas:entero); acción principal var nombre_fichero: cadena; num_tuplas: entero; v, vt: tabla [100] de punto; m: tabla [3][3] de real; error: lógico; fvar leer(nombre_fichero); num_tuplas:=LeerVectorPuntos(nombre_fichero,v); si num_tuplas <> -1 leer(nombre_fichero); error:=LeerMatriz (nombre_fichero,m); si error=FALSO ObtenerTransformado(v, num_tuplas, m, vt); OrdenarVector(num_tuplas, v); leer(nombre_fichero); EscribirVector(nombre_fichero,vt, num_tuplas); // se podría controlar también un posible error al escribir en el fichero sino escribir(“Lo siento, no se pudo abrir el fichero de la matriz”); fsi sino escribir(“Lo siento, no se pudo abrir el fichero de datos”); fsi facción función LeerVectorPuntos(ent nom: cadena, sal v: tabla[100] de punto):entero var p: punto; i: entero; f: fichero; e: lógico; fvar AbrirFich(nom,”lectura”,f,e); si e=FALSO i:=0; mientras FinFich(f)=FALSO y i < 100 LeerFich(f,p);

v[i]:=p; i:=i+1 fmientras CerrarFich(f); sino i:= -1; fsi retorna i; ffunción función LeerMatriz(ent nom:cadena, sal m: tabla[3][3] de real):lógico var c: real; i,j: entero; f: fichero; e: lógico; fvar AbrirFich(nom,”lectura”,f,e); si e=FALSO i:=0; mientras i < 3 j:=0; mientras j < 3 LeerFich(f,c); m[i][j]:=c; j := j+1; fmientras i := i+1; fmientras CerrarFich(f); retorna e; sino retorna e; fsi ffunción acción ObtenerTransformado(ent v: tabla [100] de punto, num_tuplas:entero, m: tabla[3][3] de real, sal vt: tabla [100] de punto) var i: entero; fvar i:=0; mientras i < num_tuplas vt[i].x := v[i].x*m[0][0] + v[i].y*m[1][0] + v[i].z*m[2][0] ; vt[i].y := v[i].x*m[0][1] + v[i].y*m[1][1] + v[i].z*m[2][1] ; vt[i].z := v[i].x*m[0][2] + v[i].y*m[1][2] + v[i].z*m[2][2] ; i:=i+1; fmientras facción acción OrdenarVector(ent numitems:entero, sal v: tabla[100] de punto); var i: entero; paux: punto; intercambio : lógico; fvar intercambio := verdadero; mientras intercambio=verdadero intercambio := falso

i := 0; mientras i < numitems-1 si raiz(v[i+1].x2 + v[i+1].y2 + v[i+1].z2) < raiz(v[i].x2 + v[i].y2 + v[i].z2) paux := v[i]; v[i] := v[i+1]; v[i+1] := paux; intercambio := verdadero fsi i := i+1; fmientras fmientras facción acción EscribirVector(ent nom: cadena, v: tabla [100] de punto,num_tuplas:entero); var f: fichero; i: entero; e:lógico; fvar AbrirFich(nom,”escritura”,f,e); si e=FALSO i:=0; mientras i< num_tuplas EscribirFich(f, v[i]); i:=i+1; fmientras CerrarFich(f); fsi // no se realiza nada si existe el error en la escritura del fichero de salida // por supuesto, esa posibilidad podríamos controlarla (se deja como ejercicio) facción

7. • •

Realizar en lenguaje algorítmico y en C un programa que resuelva el siguiente problema: Se dispone de un fichero, en el que en cada fila se encuentra almacenado un segmento de línea dado por dos puntos del espacio tridimensional (inicial y final). El tamaño máximo que el fichero podrá alcanzar será de 100+M segmentos de línea. Se desea obtener un fichero que contenga la polilínea formada por los segmentos de línea que unen los puntos medios de los segmentos originales

Lenguaje Algoritmico: Definiendo N=100 Utilizando Tipo punto=tupla x,y,z: real; ftupla Ftipo Tipo segmento=tupla Inicio:punto; Fin:punto; ftupla ftipo

funcion LeerFicheroSegmentos (ent nomfich: cadena, ent/sal poli: tabla[N] de segmento):entero; accion EncontrarPolilineaMedia (ent pol1: tabla[N] de segmento, ent/sal pol2: tabla[N] de segmento, ent num_segmentos: entero); accion CalcularPuntosMedios (ent pol: tabla[N] de segmento, ent/sal pm : tabla[N] de punto, ent num_segmentos: entero); funcion PuntoMedioSegmento (ent p: punto, ent q: punto):punto; accion EscribirSegmentosFichero (ent nomfich: cadena, ent pol: tabla[N] de segmento, ent num_segmentos: entero); Acción principal var num_segmentos: entero; polilinea1, polilinea2 : tabla [N] de segmento; pm: tabla[N] de punto; nomfich_entrada, nomfich_salida: cadena; fvar Leer(nomfich_entrada); num_segmentos:=LeerFicheroSegmentos(nomfich_entrada,polilinea1); si num_segmentos<>-1 EncontrarPolilineaMedia(polilinea1,polilinea2,num_segmentos); Leer(nomfich_salida); EscribirSegmentosFichero(nomfich_salida,polilinea2,num_segmentos); sino escribir(“Lo siento, hubo error en la apertura”); faccion Funcion LeerFicheroSegmentos( ent nomfich: cadena, ent/sal poli: tabla[N] de segmento):entero var s: segmento; i: entero; f: fichero; e: lógico; fvar AbrirFich(nomfich,”lectura”,f,e); si e=FALSO i:=0; mientras (FinFich(f)=FALSO y i<N) LeerFich(f,s); poli[i]:=s; i:=i+1; fmientras sino i:=-1; fsi CerrarFich(f); retorna i; ffuncion

accion EncontrarPolilineaMedia(ent pol1: tabla[N] de segmento, ent/sal pol2: tabla[N] de segmento, ent num_segmentos: entero) var pm: tabla[N] de punto; i : entero; fvar CalcularPuntosMedios(pol1,pm,num_segmentos); para i:=0 hasta num_segmentos-1 si i <> num_segmentos-1 Pol2[i].inicio:=pm[i]; Pol2[i].fin:=pm[i+1]; sino Pol2[i].inicio:=pm[i]; Pol2[i].fin:=pm[0]; // para cerrar la polilinea fsi fpara faccion accion CalcularPuntosMedios(ent pol: tabla[N] de segmento, ent/sal pm : tabla[N] de punto, ent num_segmentos: entero) var i: entero; pmedio: punto; // en realidad no hace falta fvar para i:=0 hasta num_segmentos-1 pmedio:=PuntoMedioSegmento(pol[i].inicio,pol[i].fin); pm[i]:=pmedio; fpara faccion funcion PuntoMedioSegmento(ent p: punto, ent q: punto):punto var pmedio: punto; fvar pmedio.x:=(p.x+q.x)/2; pmedio.y:=(p.y+q.y)/2; pmedio.z:=(p.z+q.z)/2; retorna pmedio; ffuncion accion EscribirSegmentosFichero(ent nomfich: cadena, ent pol: tabla[N] de segmento, ent num_segmentos: entero) var i: entero; f: fichero; e: lógico; fvar AbrirFich(nomfich,”escritura”,f,e); si e=FALSO para i:=0 hasta num_segmentos-1 EscribirFich(f,pol[i]); fpara CerrarFich (f); fsi // no controlamos si se produce el error (se deja como ejercicio) faccion

8. •

Realizar en lenguaje algorítmico y en C un programa que resuelva el siguiente problema: Se desea realizar un sistema de clasificación automática de objetos situados en puntos del plano, de tal forma que como entrada se dispone de un fichero, en el que en cada fila se encuentran almacenadas las coordenadas planas de un punto y una propiedad de cada punto que puede valer 1 ó 2, y que indica su pertenencia a la clase de puntos C1 o a la clase C2 (ver figura). El tamaño máximo que el fichero podrá alcanzar será de 100+M puntos.

2 1 0 0 1 2 ...

Fichero de Entrada: 0,0,1 0,1,1 0,2,1 0,3,2 1,0,1 1,1,1 1,2,1 1,3,1 2,0,2 2,1,1 ... • El algoritmo de clasificación será el 3-NearestNeigbourgh (3-NN), o de los tres vecinos más cercanos. De tal forma que para un punto del plano con coordenadas reales, como por ejemplo el (1.5,1.7), nos debe determinar si pertenece a la clase 1 o a la 2, estudiando los tres puntos más cercanos a él, para determinar a que clase pertenecen. El punto (1.5, 1,7) será asignado a la clase de objetos más repetida en sus tres vecinos más cercanos. Escribir el algoritmo para k-NN, siendo k cualquier número entero.

9. •

Realizar en lenguaje algorítmico y en C un programa que resuelva el siguiente problema: En un fichero (1) tenemos la descripción de una estructura metálica plana formada por barras, como en: Barra 0 1 2 3 4 NodoInicio NodoFin 0 1 1 2 0 2 2 3 1 3 TipoPerfil IPN-100 IPN-200 IPN-100 IPN-100 IPN-100

En otro fichero (2), tenemos cuanto pesa por metro cada uno de los distintos tipos de perfiles:

TipoPerfil IPN-100 IPN-200 UPN-100 ... •

Peso 175 250 150

En un último fichero (3), tenemos las coordenadas de cada nodo de la estructura en el plano: Nodo 0 1 2 3 X 10 5 5 0 Y 0 0 5 0

• •

Los ficheros (1) y (3), son definidos por el usuario de un paquete de cálculo de estructuras, el fichero (2) es propio del paquete (aunque para este ejercicio debe escribirse) Se pide :

A) Que el programa actualice el fichero (1) para que además contenga otro campo, que almacene la longitud de cada barra de la estructura B) Calcular el peso total de la estructura definida

10. Realizar en lenguaje algorítmico y en C un programa que resuelva el siguiente problema: Dados dos ficheros, el primero en el que en cada línea tenemos el dni, el nombre y la edad de una persona y el segundo en el que tenemos en cada línea el dni e información acerca de la matriculación en las asignaturas A,B,C,D y E, como se muestra (máximo 100 en cada fichero): Fichero (1): DNI 14236578 12345678 21435678 ... Fichero (2): DNI 14236578 12345678 21435678 ...

NOMBRE pepe pepi pepon

EDAD 20 19 21

A 1 0 1

BCDE 0 0 01 1 1 10 1 1 11

Se pide: • Edad media de los matriculados en cada asignatura (por pantalla). • Listados de DNI y NOMBRE de los que estén matriculados en A, B y C.

Lenguaje Algoritmico: Definiendo N=100 Utilizando Tipo persona=tupla dni: cadena nombre: cadena edad: entero ftupla Ftipo Tipo matricula=tupla dni: cadena a,b,c,d,e: booleano; ftupla ftipo // Completar con LeerFicheroPersonas // Completar con LeerFicheroDatos funcion EncontrarMatriculadosEnABC(ent datos: tabla[N] de matricula, ent num: entero, ent/sal v: tabla[N] de entero); accion ExtraerMatriculadosEnABC(ent lista: tabla[N] de persona, ent numpersonas: entero, ent v: tabla[N] de entero, ent matriculados: entero, ent/sal lista_matriculados: tabla[N] de persona); // Completar con EscribirListaFichero Acción principal var num_personas1, num_personas2, matriculados: entero; lista, lista_matriculados : tabla [N] de persona; datos: tabla[N] de matricula; v: tabla[N] de entero; nomfich_entrada1, nomfich_entrada2, nomfich_salida: cadena; fvar // se deja como ejercicio controlar los posibles errores en las aperturas de los ficheros Leer(nomfich_entrada1); numpersonas1:=LeerFicheroPersonas(nomfich_entrada1,lista); Leer(nomfich_entrada2); numpersonas2:=LeerFicheroDatos(nomfich_entrada2,datos); // el número de personas de ambos ficheros podría ser diferente matriculados:=EncontrarMatriculadosEnABC(datos,numpersonas2,v); ExtraerMatriculadosEnABC(lista,numpersonas1,v,matriculados,lista_matriculados); Leer(nomfich_salida); EscribirListaFichero(nomfich_salida, lista_matriculados, matriculados); faccion

funcion EncontrarMatriculadosEnABC(ent datos: tabla[N] de matricula, ent num: entero, ent/sal v: tabla[N] de entero) var i,j : entero; fvar j:=0; para i:=0 hasta num si (datos[i].a=1) y (datos[i].b=1) y (datos[i].c=1) v[j]:=i; // en el vector v almacenamos los indices de los matriculados j:=j+1; fsi fpara retorna j; ffuncion accion ExtraerMatriculadosEnABC(ent lista: tabla[N] de persona, ent numpersonas: entero, ent v: tabla[N] de entero, ent matriculados: entero, ent/sal lista_matriculados: tabla[N] de persona) var j : entero; fvar para j:=0 hasta matriculados-1 lista_matriculados[j]:=lista[v[j]]; fpara faccion

Bibliografía6
[AHU88] [AM97] [BB97] [BC85] [CC97] [CCM93] [CF97] [ChC87] [Fai87] [GGS93] [Joy87] [Joy92] [Knu86] [KR88] [Lip87]
6

Aho A. V., Hopcroft J. E., Ullman J. D., Estructuras de datos y algoritmos. Addison-Wesley Iberoamericana ,1988. Antonakos J. L., Mansfield K. C., Programación estructurada en C, PrenticeHall, 1997. Brassard G., Bratley P., Fundamentos de Algoritmia, Prentice Hall, 1997. Biondi J., Clavel G., Introducción a la programación. Tomo 1: algoritmos y lenguajes, Masson, 1985. Cerrada J., Collado M., Programación I, Universidad Nacional de Educación a Distancia, 1997. Castro, J.; Cucker, F.; Messeguer, X.; Rubio, A.; Solano, Ll.; Valles, B. Curso de Programación. Editorial Mc.Graw-Hill, 1993. Cerrada C., Feliu V., Estructura y tecnología de computadores I, Universidad Nacional de Educación a Distancia, 1997. Chapra, Steven C.; Canale, Raimond P. Métodos Numéricos para Ingenieros. Editorial Mc.Graw-Hill Fairley, Richard. Ingeniería de Software. Editorial McGraw-Hill, 1987. Galve, J; González, J; Sánchez, A; Velázquez, J. Algoritmica. Diseño y análisis de algoritmos funcionales e imperativos. Editorial Ra-Ma, 1993. Joyanes, L. Metodología de la Programación. Editorial Mc.Graw-Hill, 1987. Joyanes Aguilar, Luis. Fundamentos de Programación. Algoritmos y Estructuras de Datos. 2ª Edición. Editorial McGraw-Hill, 1992. Knuth, D.E. Algoritmos Fundamentales. Volumen I. Editorial Reverte, 1986. Kernighan, B; Ritchie, D. El Lenguaje de Programación C. 5ª R. Editorial Prentice-Hall, 1988. Lipschutz, S. Estructuras de Datos. Editorial Mc.Graw-Hill, 1987.

Como en los anteriores capítulos, todas las referencias bibliografías se encuentran disponibles en la biblioteca de la Escuela Politécnica Superior de Algeciras

[LS85] [PTV92] [Sch88] [Sch91] [Sch95] [SGTLL97] [SK86] [SP91] [TLL96] [WPM89]

Lewis, T; Smith, M. Estructuras de Datos. Programación y Aplicaciones. Editorial Paraninfo, 1985. Press, W; Teukolsky, S; Vetterling, W; Flannery, B. Numerical Recipes in C. The Art of Scientific Computing. 2ª Edición. Cambridge University Press, 1992. Schildt, H. C - Manual de Referencia. Editorial Mc.Graw-Hill, 1988. Schildt, H. Ansi C a su alcance. Editorial Mc.Graw-Hill, 1991. Schildt, H. Turbo C/C++ v.3.1- Manual de Referencia. Editorial Mc.GrawHill, 1995. Sanchez, P.J; Galindo, J.; Turias, I.; Lloret, I. Ejercicios Resueltos de Programación en C. Servicio de Publicaciones de la Universidad de Cádiz, 1997. Sobelman, G.; Krekelberg, D. Técnicas avanzadas en C. Desarrollo de aplicaciones. Editorial Anaya-Multimedia, 1986. Scoll P. C., Peyrin J.P., Esquemas algorítmicos fundamentales: secuencias e iteración, Masson, 1991. Turias, Ignacio; Lloret, Isidro. Guía Práctica de Programación en C. Dpto. Lenguajes y Sistemas Informáticos. UCA, 1996. Waite, M; Prata, S.; Martin, D. Programación en C. Introducción y conceptos avanzados. 2ª Edición. Editorial Anaya-Multimedia, 1989.

You're Reading a Free Preview

Descarga
scribd
/*********** DO NOT ALTER ANYTHING BELOW THIS LINE ! ************/ var s_code=s.t();if(s_code)document.write(s_code)//-->