INTRODUCCIÓN Estructura de Datos Tipos Abstractos de Datos (TAD S) Para poder obtener un programa que resuelva un problema dado, son necesarios varios pasos : La formulación y especificación del problema El diseño de una solución La implementación Las pruebas y documentación Evaluación de la solución Profs. Lorna Figueroa M. Mauricio Solar F. UTFSM 1 / 2008 L.F.M. 1 2 Como obtener a partir de un problema, un programa que lo resuelva? Lo importante es saber claramente lo que se quiere resolver (tener especificaciones claras). Hay problemas que no tienen definido un modelo claro, que sólo se puede definir experimentando. Otros se pueden plantear usando modelos formales: hay un modelamiento que se soporta en una teoría bien definida (matemática, física, ciencias de la computación, etc.) Una vez conocido el modelo del problema, se intenta resolver basándose en dicho modelo. Esta solución se alcanza mediante la aplicación de un algoritmo. Algoritmo: una secuencia finita de instrucciones, cada una de ellas con un significado muy claro, que tienen realizarse con una cantidad finita de esfuerzo y en un tiempo finito. 3 4 1
MODELO MATEMATICO ALGORITMO INFORMAL TIPOS DE DATOS ABSTRACTOS PROGRAMA EN PSEUDO- CODIGO ESTRUCTURA DE DATOS PROGRAMA EN EL LENGUAJE INSTANCIA- CIONES EJECUCION EN LA MAQUINA Especificación del problema Algoritmo Definición de TDA s Programa 5 6 Abstracción - Modelo Uno de los objetivos de la computación es resolver problemas. Normalmente los problemas son confusos y lo primero que se tiene que hacer es entender el problema para apartar los detalles no esenciales y dejar sólo los que sirven. Tu debes hacer tu propia representación abstracta o modelo del problema. Este proceso se llama abstracción. abstracción Problema Abstracción - Modelo Entonces, el modelo define una perspectiva abstracta del problema. Esto implica que el modelo se enfoca solamente en aspectos relacionados con el problema, definiendo solo las propiedades del problema. Estas propiedades incluyen los datos que son afectados, las operaciones que son identificadas por el problema. modelos 7 8 2
Tipo de datos (TD) Concepto En un lenguaje de programación, el tipo de datos de una variable (o constante o resultado de una función) está determinado por: conjunto de valores que dicha variable puede tomar conjunto de operaciones que se pueden realizar con variables del mencionado tipo (argumentos y/o resultado). Tipo de datos (TD) Ejemplo: el tipo boolean tiene dos valores: {false, true, es decir que una variable de este tipo podría tomar sólo uno de esos valores; con respecto a las operaciones cuenta con la negación, la conjunción y la disyunción cuya representación es: not, and y or respectivamente. 9 10 Estructura de Datos Representación en el computador de los datos o características relevantes de un objeto o de un concepto. Los datos o características que se considerarán relevantes dependerán del contexto en que se aplicarán. círculo C1 datos centro radio color Estructura de datos Una estructura de datos es una colección de variables organizadas de alguna manera determinada. Es una manera de almacenar y organizar datos para facilitar el acceso, modificaciones y poder operar con sus elementos. Se construyen mediante agrupamiento de elementos básicos de almacenamiento. Agrupamientos reciben un nombre que se puede usar para formar otras estructuras. 11 12 3
Estructura de datos Abstracción de Datos - TAD Para formar las agrupaciones existen varios mecanismos: Arreglo: formado por una secuencia de celdas o estructuras de tipos iguales. Cada celda de un arreglo se referencia mediante un índice. Registro: formado por una colección de celdas, campos, de tipos posiblemente distintos. Se pueden agrupar en arreglos. Un TDA es un tipo de dato definido por el programador que se puede manipular de un modo similar a los tipos de datos definidos por el lenguaje, Los TDA constituyen una forma de generalización y encapsulamiento de los aspectos más importantes de la información que se debe manejar en la resolución de un problema, sin considerar las cuestiones relativas a la implementación. 13 14 Abstracción de Datos - TAD Un TDA es una generalización de los tipos de datos básicos y de las operaciones primitivas. Abstracción de Datos - TAD Ejemplo: int vector [10]; declaración del arreglo TAD = Representación + Operaciones (estruct. de de datos) (métodos) vector sumar insertar eliminar buscar asignar 15 16 4
Definición Formalmente el el TDA es es una tripleta (D, F, F, A) A) con los los siguientes componentes: Un Un conjunto de de dominios, D Un Un conjunto de de funciones sobre los los dominios, F Abstracción de Datos - TAD Un TAD engloba dos clases de abstracciones: Abstracciones de datos. Abstracciones funcionales. Un Un conjunto de de axiomas o propiedades definidas a partir de de las las funciones y elementos de de los los dominios, A 17 18 Abstracción de Datos - TAD Abstracciones de datos Aparecen al abstraer el significado de los diferentes tipos de datos significativos que intervienen en el problema. Permiten definir nuevos tipos de datos especificando sus posibles valores y las operaciones que los manipulan. Cómo realizar la especificación formal un TDA? Definición del tipo: Se debe indicar el nombre tanto del TDA y del elemento base del mismo y/o otros TDA involucrados en la definición del TDA los invariantes de representación. Abstracciones funcionales Surgen al plantearse de una manera abstracta las operaciones significativas del problema. Permiten dar a una aplicación operaciones que no están definidas directamente en el lenguaje en el que se está Invariante de un TDA (Dominio de la estructura): Es una proposición que expresa el conjunto de valores válidos del TDA. El invariante permite saber qué elementos pertenecen o no al TDA (opcional). trabajando. 19 20 5
Cómo realizar la especificación formal un TDA? La especificación de un TDA es la descripción del comportamiento del mismo. Debe formalizarse. Indica qué hace el TDA. Especificar la sintaxis correspondiente a las operaciones propias del TDA, o primitivas del mismo. Tipos de especificaciones formales de un TDA: 1. Axiomática: expresión de la forma de las operaciones, indicando las reglas a seguir para realizar cada operación. 2. Semántica: expresión de la operatoria de las operaciones. Se especifican las consecuencias de las operaciones para el TDA. Se da mediante el lenguaje natural, o mediante especificación algebraica. Generalmente con notación funcional, se indica sobre qué conjunto actúan las operaciones y qué dan como resultado. 21 22 Descripción de las operaciones Cada operación relacionada con la estructura se describe con: Nombre de la operación. Descripción breve de su utilidad. Datos de entrada a la operación Datos que genera como salida la operación. Pre-condición: Condición que deberá cumplirse antes de utilizar la operación para que se realice sin problemas Post-condición:Condición en que queda el TDA después de ejecutar la operación. Ejemplo: Especificación Lógica del TDA Cadena Elementos: todos los caracteres alfabéticos (letras mayúsculas y minúsculas), caracteres numéricos y caracteres especiales. Estructura: hay una relación lineal entre los caracteres. Dominio: existen entre 0 y 80 caracteres en cada valor del TDA CADENA. El dominio serán todas aquellas secuencias de caracteres que cumplan con las reglas. 23 24 6
Ejemplo: Especificación Lógica del TDA Cadena Operaciones: BORRA_INICIO UTILIDAD: Sirve para eliminar el primer carácter de una cadena. ENTRADA: Cadena S sobre la que se desea eliminar el primer carácter. SALIDA: El carácter más a la izquierda de la cadena S y la cadena S modificada. PRECONDICIÓN: La cantidad de caracteres es mayor que cero. POSTCONDICIÓN: La cadena S tiene todos los caracteres, menos el primero. Ejemplo: Especificación Lógica del TDA Cadena Operaciones: (continuación) AGREGA_FINAL UTILIDAD: Sirve para agregar un carácter al final de una cadena. ENTRADA: Cadena S y el carácter L, que se añadirá a la cadena S. SALIDA: Cadena S modificada. PRECONDICIÓN: La cantidad de caracteres en S es menor que 80. POSTCONDICIÓN: La cadena S tiene el carácter L que queda al extremo derecho de la cadena. 25 26 Ejemplo: Especificación Lógica del TDA Cadena Operaciones: (continuación) VACÍA UTILIDAD: Sirve para verificar si una cadena esta vacía o no. ENTRADA: Cadena S que se verificará SALIDA: VERDADERO si la cadena S no tiene caracteres, FALSO en caso contrario. PRECONDICIÓN : Ninguna POSTCONDICIÓN: Ninguna (pues la cadena S no se modifica). Ejemplo: Especificación Lógica del TDA Cadena Operaciones: (continuación) LLENA UTILIDAD: Sirve para verificar si una cadena esta llena o no. ENTRADA: cadena S que será verificada. SALIDA: VERDADERO si la cadena S contiene ya 80 caracteres, FALSO en caso contrario. PRECONDICIÓN : Ninguna POSTCONDICIÓN: Ninguna (pues la cadena S no se modifica). 27 28 7
Ejemplo: Especificación Lógica del TDA Cadena TAD s - Representación Operaciones: (continuación) INVIERTE UTILIDAD: Sirve para invertir el orden de los caracteres en una cadena. ENTRADA: Cadena S a la que se desea invertir el orden de los caracteres. SALIDA: Cadena S modificada. PRECONDICIÓN: Ninguna POSTCONDICIÓN: La secuencia de caracteres en la cadena S se invierte, de forma que el primer carácter Es la forma concreta en que se representan los datos en un determinado lenguaje de programación. Se debe ocultar la representación de los elementos del tipo de modo que sólo se pueda actuar sobre ellos con las operaciones proporcionadas. Una vez definido se podrán declarar variables de ese tipo y operar con ellas. 29 30 TAD s - Implementación el TDA NumeroComplejo Es la forma específica en que se expresan las operaciones. Aquí se considerará la estructura de datos más conveniente. Está dado por un grupo de instrucciones que serán ejecutadas por el computador, y se escribe en un lenguaje de programación. Cada implementación corresponde a alguna especificación. Normalmente la implementación del tipo se realiza en un módulo separado que será enlazado al programa principal. Los algoritmos más la representación da como resultado una implementación del TAD. 31 Definición del tipo Numero complejo: Conjunto de pares de elementos (a,b) de tipo entero. Operaciones: descripción de cada una de elas suma : NumeroComplejo NumeroComplejo NumeroComplejo suma((x, y), (u, v)) = (x + u, y + v) producto : NumeroComplejo NumeroComplejo NumeroComplejo producto((x, y), ((u, v), = (xu yv, xv + yu) 32 8
el TDA NumeroRacional Definición del tipo Numero racional: Conjunto de pares de elementos (a,b) de tipo entero, con b 0. Operaciones: CrearRacional: a, b = (a,b) División: (a,b) / (c,d) = (a*d, b*c) Numerador: (a,b) = a Denominador: (a,b) = b ValorReal: (a,b) = a/b Potencia: (a,b)^c = (a^c, b^c) 33 Editor de archivos secuenciales con las operaciones: Crear un nuevo archivo, Insertar, Reemplazar, Eliminar, Avanzar y retroceder, actuando siempre sobre el registro actual. 34 Operaciones: Archivo_Nuevo (Archivo): Crea un archivo nuevo sin introducir ningún registro (número de registros es 0). Insertar (Archivo, Registro): Inserta un registro después del registro actual y el nuevo pasa a ser el actual. Reemplazar (Archivo, Registro): Cambia el registro actual por el nuevo. Eliminar (Archivo): Borra el registro actual y una vez eliminado el actual pasa a ser el siguiente. Avanzar (Archivo): El registro siguiente pasa a ser el actual. Retroceder (Archivo): El registro anterior pasa a ser el actual. Implementación de las operaciones: Archivo_Nuevo (Archivo) { Longitud = 0; Reg_Actual = 0; 35 36 9
Insertar (Archivo, RegNuevo) { for (j = Longitud; j <= RegActual; j--) Archivo [j+1] = Archivo[j]; Archivo[RegActual+1] = RegNuevo; Longitud ++; RegActual ++; Retroceder (Archivo) { if RegActual!= 0 RegActual --; 37 38 Eliminar (Archivo) { if RegActual!= 0 for( j =Actual; j <= Longitud-1; j++) Archivo[j] = Archivo[j+1]; if RegActual >Longitud RegActual --; Avanzar (Archivo) { if RegActual!= Longitud RegActual ++; 39 40 10
Operación Reemplazar (Archivo,RegNuevo) { if RegActual!= 0 Archivo[RegActual] = RegNuevo; r1 r1 = Crear_Racional (2, (2, 3); 3); r2 r2 = Crear_Racional (5, (5, 7); 7); // // s es es la la suma de de r1 r1 y r2 r2 s = Crear_Racional ( Numerador( r1 r1 ) * Denominador ( r2 r2 ) + Numerador (( r2 r2 ))* Denominador (( r1 r1 ), ), Denominador (( r1 r1 ))* Denominador (( r2 r2 ) ); ); printf( %d // %d,, Numerador (( s ), ), Denominador (( s )))) 41 42 ESPECIFICACIÓN Racional Crear_Racional (Entero n,d) n,d) {{ Necesita: dos dos valores enteros, n y d. d. Produce: el el número racional n // d. d. Error: si si d es es cero. Implementación #define MAX 100 typedef struct Racional { int intnum, den; ; ; Racional info[max]; // // arreglo para almacenar los los racionales int intultimo = -1; -1; // // para controlar el el tamaño del del arreglo Entero Numerador (Racional r r )) {{ Necesita: un un racional r. r. Produce: el el numerador de de r. r. 1 2 3 4 Un racional MAX Entero Denominador (Racional r r )) {{ Necesita: un un racional r. r. Produce: el el denominador de de r. r. 43 info 3 8 9 5 17 5 último num den 44 11
Implementación int intcrear_racional (int n, n, int intd, d, int inti) i) { if if (d (d == == 0) 0) { printf("\n Error:Division por cero"); getch(); exit(0); else { info[i].num = n; n; info[i].den = d; d; ultimo++; return ultimo; Implementación int int Numerador (int r) r) { return info[r].num; int int Denominador (int r) r) { return info[r].den; 45 46 Implementación void Imprime_Racional(void) { int intnum; printf("\nindique la la posicion del del racional que quiere ver: "); "); scanf("%d", &num); if( if( num >= >= ultimo) printf( \n Error, fuera de de rango ); else printf( "\nracional ingresado es es ::%d/%d en en la la posicion %d", Numerador(num), Denominador(num), num); getch(); Implementación #include <stdio.h> #include <stdlib.h> #include <conio.h> #define MAX 100 typedef struct Racional { int intnum, den; ; ; Racional info[max]; // // arreglo donde se se almacenaran los los // // numeros racionales int intultimo = -1; -1; 47 48 12
Implementación int intmain() { int intnume, deno, pos, i, i, n; n; printf("\n Cuantos datos? "); "); scanf("%d",&n); if if (( n >= >= ultimo) { printf( \n Error, fuera de de rango ); return 1; 1; else for(i = 0; 0; i i < n; n; i++) { printf("\nnumerador: "); "); scanf("%d", &nume); printf("\ndenominador: "); "); scanf("%d", &deno); pos = Crear_Racional(nume, deno, i); i); Imprime_Racional(); return 0; 0; 49 13