lenguaje algoritmico 5

35
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 tablas 1 . 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 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.

Transcript of lenguaje algoritmico 5

Page 1: lenguaje algoritmico 5

TUPLASIntroducción a las Estructuras de DatosDefinición de nuevos tipos de datosManipulación de tuplas

Vectores de tuplasLectura/escritura de Tuplas desde teclado y fichero

Funciones y acciones que devuelven tuplasEjercicio completoEjercicios 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 tipos de datos a partir de los ya existentes, de forma que las nuevas variables de estos 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.

Page 2: lenguaje algoritmico 5

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

TipoPersona=tupla

Nombre: cadenaEdad: enteroTelefono: cadena

ftuplaFtipo

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:= 23p.telefono:= ”956662112”

Podemos asignar variables de tipo estructura directamente (por ejemplo, para dos hermanos gemelos):

q:=pq.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.

Page 3: lenguaje algoritmico 5

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)

TipoAlumno=tupla

Datos: personaNotas: tabla[50] de realCurso: entero

ftuplaFtipo

De esta forma, podemos definir variables de este nuevo tipo y darle valores:

x,y: alumno

x.curso:= 1x.notas[0]:= 5.0x.notas[1]:= 7.5x.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 personalista_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.

Page 4: lenguaje algoritmico 5

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)varp: personai: enterofvari:=0leer(p)mientras p.nombre < > “fin” y i < 100 // para no pasarnos del tamaño definido

v[i]:=pi:=i+1leer(p) // se puede leer( ) una estructura

fmientrasnumero_personas:=i // devolvemos el número de personas que hay en el vectorfacció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 23 956662112Carlos 24 956661221…

accion LeerFicheroTuplas (ent nomfich: cadena, sal v:tabla[100] de persona, sal numero_personas: entero)

varp: persona; i: enterof: fichero; e: lógicofvarAbrirFich(nomfich,”lectura”,f,e)si (no e)

i:=0mientras (no FinFich(f)) y i<100

LeerFich(f,p)v[i]:=pi:=i+1

fmientrasnumero_personas:=i

sinonumero_personas:=-1 // para controlar desde el exterior el error

fsiCerrarFich(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.

Page 5: lenguaje algoritmico 5

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)

vari: enterof: ficheroe: lógicofvarAbrirFich(nomfich,”escritura”,f,e)si e=FALSO

para i:=0 hasta numero_personas-1EscribirFich(f,v[i])

fparafsiCerrarFich(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

varI: enteroedad_med: realfvaredad_med:=0.0para i:=0 hasta numero_amigos-1

edad_med:=edad_med+lista_amigos[i].edadfpararetorna (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:

Tipopunto=tupla

x,y: realftupla

Ftipo

función PuntoMedio (ent p: punto, ent q: punto): puntovarpm: puntofvarpm.x:= (p.x+q.x)/2.0pm.y:= (p.y+q.y)/2.0retorna pm;ffunción

Page 6: lenguaje algoritmico 5

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.0pm.y:= (p.y+q.y)/2.0facció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

vari: entero;persona_nula: persona;fvarpersona_nula:={“”,-1,””}i:=0mientras lista_amigos[i].telefono < > telefono_sin_nombre y i < numero_amigos

i: = i+1 // se hace un recorrido hasta encontrarlo o terminarfmientrassi i < > numero_amigos

retorna lista_amigos[i] // una personasino

retorna persona_nula // para su control desde el exterior de esta funciónfsiffunció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 tiposTipo

Persona=tuplaNombre: cadenaEdad: enteroTelefono: cadena

ftuplaFtipo

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

Page 7: lenguaje algoritmico 5

// prototipos de acciones y/o funciones

función LeerFicheroTuplas (ent nomfich: cadena, sal v:tabla[N] de persona): enterofunción BuscaEdad (ent v:tabla[N] de persona, ent num:entero, ent edad:entero,

sal v_misma_edad:tabla[N] de persona): enteroacción EscribirFicheroTuplas (ent nomfich: cadena, ent v:tabla[N] de persona,

ent numero_personas: entero)

Acción Principalvarnomfich1,nomfich2: cadenalista, lista_misma_edad:tabla[N] de personaedad,num_personas, num_edad: enterofvarleer(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)

sinoescribir(‘Error en la apertura del fichero de datos’)

fsiescribir(‘Fin del programa’)facción

función LeerFicheroTuplas (ent nomfich: cadena, sal v:tabla[100] de persona): enterovarp: personai,num_personas: enterof: ficheroe: lógicofvarAbrirFich(nomfich,”lectura”,f,e)si (no e)

i:=0mientras (no FinFich(f)) y i<100

LeerFich(f,p)v[i]:=pi:=i+1

fmientrasnumero_personas:=i

sinonumero_personas:=-1 // para controlar desde el exterior el error

fsiCerrarFich(f)facción

Page 8: lenguaje algoritmico 5

acción EscribirFicheroTuplas (ent nomfich: cadena, ent v:tabla[100] de persona, ent numero_personas: entero)

vari: enterof: ficheroe: lógicofvarAbrirFich(nomfich,”escritura”,f,e)si e=FALSO

para i:=0 hasta numero_personas-1EscribirFich(f,v[i])

fparafsiCerrarFich(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

vari,k: enterofvarpara i:=0 hasta num-1

k:=0si v[i].edad = edad

v_misma_edad[k]:=v[i]k:=k+1

fsifpararetorna kffunció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:

UtilizandoTipo raizdoble = tupla

sol1: realsol2: real

ftuplaftipofunción sol_ec_2grado(ent a, b, c: real): raizdoble

Page 9: lenguaje algoritmico 5

acción principal var a2, a1, a0: realsolucion: raizdoble fvarleer(a2, a1, a0)solucion:=sol_ec_2grado(a2, a1, a0)escribir(solucion)facción

función sol_ec_2grado(ent a, b, c: real): raizdoblevarr: raizdoblefvarr.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);}

Page 10: lenguaje algoritmico 5

/************************************************************************//* 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.

4. 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)

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.

Page 11: lenguaje algoritmico 5

Lenguaje Algorítmico:

Utilizando

Tipo

persona = tuplanombre: cadenaedad: entero

ftuplaftipo

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: enterolista: 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);

sinoEscribir(“Lo siento, no se puedo abrir el fichero de datos.”);

fsifacción

acción LeerFichero (ent nomfich: cadena; sal v:tabla [10] de persona; sal numitems : entero)

varp: persona;i: entero;f: fichero;e:lógico;fvarAbrirFich(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;

fmientrasnumitems:=i;CerrarFich(f);

sinonumitems:=-1;

fsifacción

Page 12: lenguaje algoritmico 5

acción OrdenarVector(ent numitems:entero , ent/sal v: tabla[10] de persona)var

i: entero;paux: persona;intercambio : lógico;

fvarintercambio := verdadero;mientras intercambio=verdadero

intercambio := falsoi := 0;mientras i < numitems-1

si v[i+1].edad < v[i].edadpaux := v[i];v[i] := v[i+1];v[i+1] := paux;intercambio := verdadero

fsii := i+1;

fmientrasfmientrasfacción

acción EscribirFichero (ent nomfich: cadena; ent v:tabla [10] de persona; ent numitems : entero)

vari: entero;f:fichero;e:lógico;fvarAbrirFich(nomfich,”escritura”,f,e);si e=FALSO

para i:=0 hasta numitems-1 EscribirFich(f,v[i]);

fparaCerrarFich (f);

fsifacció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);

Page 13: lenguaje algoritmico 5

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);}

elseprintf(“\nNo se pudo abrir el fichero de datos.”);

}

void LeerFichero (char nomfich[20+1], persona v[10], int *numitems){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], persona v[10], int numitems)

{FILE *S;int i;

S = fopen (nomfich,"wt");

Page 14: lenguaje algoritmico 5

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:

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.

Page 15: lenguaje algoritmico 5

Lenguaje Algorítmico

Utilizando

tipotupla = punto

x,y,z: real;ftupla

ftipofunció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 principalvar

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 <> -1leer(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

sinoescribir(“Lo siento, no se pudo abrir el fichero de la matriz”);

fsisino

escribir(“Lo siento, no se pudo abrir el fichero de datos”);fsifacción

función LeerVectorPuntos(ent nom: cadena, sal v: tabla[100] de punto):enterovar

p: punto;i: entero;f: fichero;e: lógico;

fvarAbrirFich(nom,”lectura”,f,e);si e=FALSO

i:=0;mientras FinFich(f)=FALSO y i < 100

LeerFich(f,p);

Page 16: lenguaje algoritmico 5

v[i]:=p;i:=i+1

fmientrasCerrarFich(f);

sinoi:= -1;

fsiretorna i;ffunción

función LeerMatriz(ent nom:cadena, sal m: tabla[3][3] de real):lógicovar

c: real;i,j: entero;f: fichero;e: lógico;

fvarAbrirFich(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;

fmientrasi := i+1;

fmientrasCerrarFich(f);retorna e;

sinoretorna e;

fsiffunció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;fvari:=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;

fmientrasfacción

acción OrdenarVector(ent numitems:entero, sal v: tabla[100] de punto);var

i: entero;paux: punto;intercambio : lógico;

fvarintercambio := verdadero;mientras intercambio=verdadero

intercambio := falso

Page 17: lenguaje algoritmico 5

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

fsii := i+1;

fmientrasfmientrasfacción

acción EscribirVector(ent nom: cadena, v: tabla [100] de punto,num_tuplas:entero);var

f: fichero;i: entero;e:lógico;

fvarAbrirFich(nom,”escritura”,f,e);si e=FALSO

i:=0;mientras i< num_tuplas

EscribirFich(f, v[i]);i:=i+1;

fmientrasCerrarFich(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:

DefiniendoN=100

UtilizandoTipo

punto=tuplax,y,z: real;

ftuplaFtipoTipo

segmento=tuplaInicio:punto;Fin:punto;

ftuplaftipo

Page 18: lenguaje algoritmico 5

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 principalvarnum_segmentos: entero;polilinea1, polilinea2 : tabla [N] de segmento;pm: tabla[N] de punto;nomfich_entrada, nomfich_salida: cadena;fvarLeer(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);

sinoescribir(“Lo siento, hubo error en la apertura”);

faccion

Funcion LeerFicheroSegmentos( ent nomfich: cadena, ent/sal poli: tabla[N] de segmento):entero

vars: segmento;i: entero;f: fichero;e: lógico;fvarAbrirFich(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;

fmientrassino

i:=-1;fsiCerrarFich(f);retorna i;ffuncion

Page 19: lenguaje algoritmico 5

accion EncontrarPolilineaMedia(ent pol1: tabla[N] de segmento,ent/sal pol2: tabla[N] de segmento,ent num_segmentos: entero)

varpm: tabla[N] de punto;i : entero;fvarCalcularPuntosMedios(pol1,pm,num_segmentos);para i:=0 hasta num_segmentos-1

si i <> num_segmentos-1Pol2[i].inicio:=pm[i];Pol2[i].fin:=pm[i+1];

sinoPol2[i].inicio:=pm[i];Pol2[i].fin:=pm[0]; // para cerrar la polilinea

fsifparafaccion

accion CalcularPuntosMedios(ent pol: tabla[N] de segmento,ent/sal pm : tabla[N] de punto,ent num_segmentos: entero)

vari: entero;pmedio: punto; // en realidad no hace faltafvarpara i:=0 hasta num_segmentos-1

pmedio:=PuntoMedioSegmento(pol[i].inicio,pol[i].fin);pm[i]:=pmedio;

fparafaccion

funcion PuntoMedioSegmento(ent p: punto, ent q: punto):puntovarpmedio: punto;fvarpmedio.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)

vari: entero;f: fichero;e: lógico;fvarAbrirFich(nomfich,”escritura”,f,e);si e=FALSO

para i:=0 hasta num_segmentos-1EscribirFich(f,pol[i]);

fparaCerrarFich (f);

fsi // no controlamos si se produce el error (se deja como ejercicio)faccion

Page 20: lenguaje algoritmico 5

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.

Fichero de Entrada:

0,0,10,1,10,2,10,3,21,0,11,1,11,2,11,3,12,0,22,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 NodoInicio NodoFin TipoPerfil0 0 1 IPN-1001 1 2 IPN-2002 0 2 IPN-1003 2 3 IPN-1004 1 3 IPN-100

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

Page 21: lenguaje algoritmico 5

TipoPerfil PesoIPN-100 175IPN-200 250UPN-100 150...

En un último fichero (3), tenemos las coordenadas de cada nodo de la estructura en el plano:

Nodo X Y0 10 01 5 02 5 53 0 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 NOMBRE EDAD14236578 pepe 2012345678 pepi 1921435678 pepon 21...

Fichero (2):DNI A B C D E14236578 1 0 0 0 112345678 0 1 1 1 021435678 1 1 1 1 1...

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.

Page 22: lenguaje algoritmico 5

Lenguaje Algoritmico:

DefiniendoN=100

UtilizandoTipo

persona=tupladni: cadenanombre: cadenaedad: entero

ftuplaFtipoTipo

matricula=tupladni: cadenaa,b,c,d,e: booleano;

ftuplaftipo

// 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 principalvarnum_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 ficherosLeer(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 diferentematriculados:=EncontrarMatriculadosEnABC(datos,numpersonas2,v);ExtraerMatriculadosEnABC(lista,numpersonas1,v,matriculados,lista_matriculados);Leer(nomfich_salida);EscribirListaFichero(nomfich_salida, lista_matriculados, matriculados);faccion

Page 23: lenguaje algoritmico 5

funcion EncontrarMatriculadosEnABC(ent datos: tabla[N] de matricula,ent num: entero,ent/sal v: tabla[N] de entero)

vari,j : entero;fvarj:=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 matriculadosj:=j+1;

fsifpararetorna 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)

varj : entero;fvarpara j:=0 hasta matriculados-1

lista_matriculados[j]:=lista[v[j]];fparafaccion

Bibliografía6

[AHU88] Aho A. V., Hopcroft J. E., Ullman J. D., Estructuras de datos y algoritmos. Addison-Wesley Iberoamericana ,1988.

[AM97] Antonakos J. L., Mansfield K. C., Programación estructurada en C , PrenticeHall, 1997.

[BB97] Brassard G., Bratley P., Fundamentos de Algoritmia, Prentice Hall, 1997.[BC85] Biondi J., Clavel G., Introducción a la programación. Tomo 1: algoritmos y

lenguajes, Masson, 1985.[CC97] Cerrada J., Collado M., Programación I, Universidad Nacional de Educación a

Distancia, 1997.[CCM93] Castro, J.; Cucker, F.; Messeguer, X.; Rubio, A.; Solano, Ll.; Valles, B. Curso

de Programación. Editorial Mc.Graw-Hill, 1993.[CF97] Cerrada C., Feliu V., Estructura y tecnología de computadores I , Universidad

Nacional de Educación a Distancia, 1997.[ChC87] Chapra, Steven C.; Canale, Raimond P. Métodos Numéricos para Ingenieros .

Editorial Mc.Graw-Hill[Fai87] Fairley, Richard. Ingeniería de Software. Editorial McGraw-Hill, 1987.[GGS93] 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.[Joy87] Joyanes, L. Metodología de la Programación . Editorial Mc.Graw-Hill, 1987.[Joy92] Joyanes Aguilar, Luis. Fundamentos de Programación. Algoritmos y

Estructuras de Datos. 2ª Edición. Editorial McGraw-Hill, 1992.[Knu86] Knuth, D.E. Algoritmos Fundamentales. Volumen I. Editorial Reverte, 1986.[KR88] Kernighan, B; Ritchie, D. El Lenguaje de Programación C . 5ª R. Editorial

Prentice-Hall, 1988.[Lip87] Lipschutz, S. Estructuras de Datos. Editorial Mc.Graw-Hill, 1987.

6 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

Page 24: lenguaje algoritmico 5

[LS85] Lewis, T; Smith, M. Estructuras de Datos. Programación y Aplicaciones . Editorial Paraninfo, 1985.

[PTV92] Press, W; Teukolsky, S; Vetterling, W; Flannery, B. Numerical Recipes in C. The Art of Scientific Computing . 2ª Edición. Cambridge University Press, 1992.

[Sch88] Schildt, H. C - Manual de Referencia. Editorial Mc.Graw-Hill, 1988.[Sch91] Schildt, H. Ansi C a su alcance. Editorial Mc.Graw-Hill, 1991.[Sch95] Schildt, H. Turbo C/C++ v.3.1- Manual de Referencia. Editorial Mc.Graw-

Hill, 1995.[SGTLL97] 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.

[SK86] Sobelman, G.; Krekelberg, D. Técnicas avanzadas en C. Desarrollo de aplicaciones. Editorial Anaya-Multimedia, 1986.

[SP91] Scoll P. C., Peyrin J.P., Esquemas algorítmicos fundamentales: secuencias e iteración, Masson, 1991.

[TLL96] Turias, Ignacio; Lloret, Isidro. Guía Práctica de Programación en C . Dpto. Lenguajes y Sistemas Informáticos. UCA, 1996.

[WPM89] Waite, M; Prata, S.; Martin, D. Programación en C. Introducción y conceptos avanzados. 2ª Edición. Editorial Anaya-Multimedia, 1989.