From 55ed5c037a5091f000a55903a2b7d69b3ea4950d Mon Sep 17 00:00:00 2001 From: Manuel Vergara Date: Sun, 19 May 2024 20:22:09 +0200 Subject: [PATCH] Update PR3 --- fundamentos-programacion/PR3/README.md | 439 ++++++++++++++++++++++++- 1 file changed, 437 insertions(+), 2 deletions(-) diff --git a/fundamentos-programacion/PR3/README.md b/fundamentos-programacion/PR3/README.md index 3c07ede..d532531 100644 --- a/fundamentos-programacion/PR3/README.md +++ b/fundamentos-programacion/PR3/README.md @@ -62,7 +62,7 @@ end var ``` ```c -#include +#include #define MAX_ELEMENTS length typedef struct { @@ -98,7 +98,7 @@ end var ```c -#include +#include #include #define MAX_GATES 40 @@ -114,26 +114,461 @@ tGates bulding2; ### 16.1.2 Acceso a los elementos de una tabla +Podemos acceder a los diferentes elementos de una tabla de manera similar a como lo hacíamos con los vectores, pero teniendo en cuenta que se trata de una tupla. + + +```alg +const + K: integer = 10; + MAX_GATES: integer = 40; +end const + +type + tGates = record + stateGates: vector[MAX_GATES] of boolean; + numGates: integer; + end record +end type + +{header of fillTable} +action fillTable (out Building: tGates); + +algorithm checkDoors + var + building1: tGates; + building2: tGates; + p: integer; + b: boolean; + c: boolean; + end var + + c := true; + fillTable(building1); + {the following statements treat the element of the table as variables} + {assigns the third element of the table building1 to the variable b} + b:= building1.stateGates[3]; + + {assigns the value of the variable c to the Kth gate of building1, assuming that K is a constant such that 1 ≤ K≤ 40} + building1.stateGates[K]:= c; + + {assigns the value of the first gate of building1 to the gate 2*p +5 as long as 1 ≤ 2*p+5 ≤ 40} + building1.stateGates[2*p+5]:= building1.stateGates[1]; + +end algorithm +``` + +```c +#include +#include +#define K 10 +#define MAX_GATES 40 + +typedef struct { + bool stateGates[MAX_GATES]; + int numGates; +} tGates; + +void fillTable (tGates *Building); + +int main(int argc, char** argv) { + tGates building1; + tGates building2; + int p; + bool b; + bool c = true; + + /* the following statements treat the elements of the table as variables */ + fillTable(&building1); + + /* assigns the third element of the table building1 to the variable b */ + b = building1.stateGates[2]; + + /* assigns the value of the variable c to the kth gate of building1, assuming that k is a constant such that 1 ≤ K + ≤ 40 */ + building1.stateGates[K-1] = c; + + /* assigns the value of the first gate of building1 to the gate 2*p +5 as long as 1 ≤ 2*p+5 ≤ 40 */ + building1.stateGates[2*p+5-1] = building1.stateGates[0]; + + return 0; +} +``` + +Comentarios: +- En el lenguaje algorítmico las tablas se indexan empezando con el número 1 mientras en C se indexan a partir del 0. +- Algunos lenguajes de programación permiten indexar con culquier rango, por ejemplo, del 10 al 60. +- Durante la ejecución es importante controlar que el índice siempe esté dentro de los límites esperados para evitar errores. + ### 16.1.3 Ejemplo +Una empresa con diversos cines de tipo multisala. Sabemos que el cine más grande tiene 20 salas. + +Creamos una tabla para guardar la recaudación de cada sala pero que sirva para cualquiera de los cines. Es decir, definimos una tabla que pueda guardar hasta 20 importes reales. La tabla no siempre se llemará ya que dependerá del número de salas que tenga cada cine. + +```alg +const + MAX_THEATERS: integer = 20; +end const + +type + tTheaters = record + collect: vector[MAX_THEATERS] of real; + numTheaters: integer; + end record +end type + +var + santalo: tTheaters; + sants: tTheaters; +end var +``` + +```c +#include +/* Definition of a constant to indicate the size of the table */ +#define MAX_THEATERS 20 + +typedef struct { + float collect[MAX_THEATERS]; + int numTheaters; +} tTheaters; + +/*var declaration assuming two movies */ +tTheaters santalo; +tTheaters sants; +``` + ## 16.2 Inicialización de una tabla +Las variables de tipo tabla, como todas las variables, deben inicializarse antes de ser utilizadas. En el caso de las tablas, la manera de inicializarlas es indicando que está vacía. + +Lo hacemos asignando 0 al número de elementos ocupados en la tabla. Volviendo al anterior ejemplo, si queremos indicar que los cines inicialmente no tienen ninguna recaudación, debemos hacer lo siguiente: + +```alg +const + MAX_THEATERS: integer = 20; +end const + +type + tTheaters = record + collect: vector[MAX_THEATERS] of real; + numTheaters: integer; + end record +end type + +algorithm initTheaters + var + santalo: tTheaters; + sants: tTheaters; + end var + + {table initialitation, setting the number of theater to 0} + santalo.numTheaters := 0; + sants.numTheaters := 0; +end algorithm +``` + +```c +#include +#define MAX_THEATERS 20 + +typedef struct { + float collect[MAX_THEATERS]; + int numTheaters; +} tTheaters; + +/var declaration */ +tTheaters santalo; +tTheaters sants; + +int main(int argc, char** argv) { + /* table initialitation, setting the number of theater to 0 */ + santalo.numTheaters = 0; + sants.numTheaters = 0; + + return 0; +} +``` + ## 16.3 Carga de datos a partir de una secuencia +Una operación habitual es carga la tabla con información recogida en el canal estándar de entrada. + +Los datos vienen dados con una serie de reales (una secuencia de reales) que leemos del canal estándar y el valor -1.0 indica que es el final de los datos (fin de la secuencia de entrada). + + +Continuamos con el ejemplo anterior y, para una mejor estructura, aislamos la lectura de la información en un acción. + +```alg +const + MAX_THEATERS: integer = 20; + END_SEQ: real = -1.0; +end const + +type + tTheater = record + collect: vector[MAX_THEATERS] of real; + numTheaters: integer; + end record +end type + +action fillTable(out movieTheater: tTheater); + var + temp: real; + end var + + {table initialization} + movieTheater.numTheaters:=0; + temp:= readReal(); {we read the first number} + + {iteration while the read number is not -1} + while temp ≠ END_SEQ do + {Save the read number in the table.} + movieTheater.collect[movieTheater.numTheaters+1]:= temp; + movieTheater.numTheaters:= movieTheater.numTheaters + 1; + temp:= readReal(); + end while +end action +``` + +```c +#include +#define END_SEQ -1.0 +#define MAX_THEATERS 20 + +typedef struct { + float collect[MAX_THEATERS]; + int numTheaters; +} tTheater; + +void fillTable(tTheater *movieTheater) { + /* var definition */ + float temp; + + /* table initialization */ + movieTheater->numTheaters = 0; + scanf("%f", &temp); /* we read the first number */ + + /* iteration while the read number is not -1 */ + while (temp != END_SEQ) { + /* Save the read number in the table. */ + movieTheater->collect[movieTheater->numTheaters] = temp; + movieTheater->numTheaters = movieTheater->numTheaters + 1; + temp = readReal(); + } +} +``` + +Comentarios: +- Cada elemento de la tabla se trata como una variable. +- Antes de entrar en la iteración se lee el primer elemento. Así, antes de entrar en el bucle ya se puede comprobar si el valor del elemento es el final de la secuencia o no. +- En cada iteración incrementamos el valor de `numTheaters` para indicar que hay un elemento más en la tabla. +- A la acción le pasamos un valor de entrada/salida de tipo tabla. La acción modifica el valor de la tabla con los datos introducidos. +- En el lenguaje algorítmico el índice empieza en 1 mientras que en C empieza en 0. +- Cuando se pasa una estructura como parámetro de entrada/salida para acceder a los campos de la tupla (record) en lenguaje algorítmico se usa el punto (.) y en C se usa la notación ->. + ## 16.4 Recorrido de una tabla +Para recorrer una tabla se puede hacer de dos maneras: +- Recorrido secuencial: se recorren todos los elementos de la tabla uno a uno. +- Recorrido por búsqueda: se busca un elemento en la tabla y se recorre a partir de él. + +Siguiendo con el ejemplo anterior, vamos a realizar la simulación de un aumento del precio al 20%. Con lo cuál, vamos a aislar en una acción la operación de recorrer la tabla para multiplicar cada uno de sus elementos por 1.2. + +```alg +const + MAX_THEATERS: integer = 20; + END_SEQ: real = -1.0; +end const + +type + tTheater = record + collect: vector[MAX_THEATERS] of real; + numTheaters: integer; + end record +end type + +action update(inout movieTheater: tTheater); + var + i: integer; + end var + + {iteration. We can use a for ... do iteration because we know the exact number of element of the table} + for i:= 1 to movieTheater.numTheaters do + movieTheater.collect[i]:= movieTheater.collect[i]*1.2; + end for +end action +``` + +```c +#include +#define END_SEQ -1.0 +#define MAX_THEATERS 20 + +typedef struct { + float collect[MAX_THEATERS]; + int numTheaters; +} tTheater; + +void update(tTheater *movieTheater) { + /* var definition */ + int i; + + /* iteration. We can use a for ... do iteration because we know the exact number of element of the table */ + for (i = 0; i < movieTheater->numTheaters; i++) { + movieTheater->collect[i] = movieTheater->collect[i] * 1.2; + } +} +``` + +Comentarios: +- Para realizar el recorrido completo, podemos hacerlo utilizando el for ... do para iterar sobre todos los elementos de la tabla ya que sabemos exactamente cuántos elementos hay presentes. +- En C la iteración se hace de 0 a `movieTheater.numTheaters - 1` ya que el índice de la tabla empieza en 0 y en lenguaje algorítmico empieza en 1. + ### 16.4.1 Ejemplo: lectura y recurrido +Ahora vamos a realizar un algoritmo que lea del canal estándar la secuencia con la recaudación de las salas del cine, la muestre por el canal estándar, calcule el porcentaje indicado de sus elementos y la vuelva a mostrar por el canal estándar de salida. + +Usaremos una acción para mostrar el contenido de la tabla: + +```alg +const + MAX_THEATERS: integer = 20; + END_SEQ: real = -1.0; +end const + +type + tTheater = record + collect: vector[MAX_THEATERS] of real; + numTheaters: integer; + end record +end type + +algorithm simulation + var + santalo: tTheater; + end var + + fillTable(santalo); + printTable(santalo); + update(santalo); + printTable(santalo); +end algorithm + +action fillTable(out movieTheater: tTheater); + var + temp: real; + end var + + {table initialization} + movieTheater.numTheaters:=0; + temp:= readReal(); {we read the first number} + + {iteration while the read number is not -1} + while temp ≠ END_SEQ do + {Save the read number in the table} + movieTheater.numTheaters:=movieTheater.numTheaters + 1; + movieTheater.collect[movieTheater.numTheaters]:= temp; + temp:= readReal(); + end while +end action + +action update(inout movieTheater: tTheater) + var + i: integer; + end var + + {iteration. We can use a for ... do iteration because we know the exact number of element of the table} + for i:=1 to movieTheater.numTheaters do + movieTheater.collect[i]:= movieTheater.collect[i] * 1.20; + end for +end action + +action printTable(in movieTheater: tTheater) + var + i: integer; + end var + + {iteration. We can use a for ... do iteration because we know the exact number of element of the table} + for i:=1 to movieTheater.numTheaters do + writeReal(movieTheater.collect[i]); + end for +end action +``` + +```c +#include +#define END_SEQ -1.0 +#define MAX_THEATERS 20 + +typedef struct { + float collect[MAX_THEATERS]; + int numTheaters; +} tTheater; + +void fillTable(tTheater *movieTheater) { + /* var definition */ + float temp; + + /* table initialization */ + movieTheater->numTheaters = 0; + scanf("%f", &temp); /* we read the first number */ + + /* iteration while the read number is not -1 */ + while (temp != END_SEQ) { + /* Save the read number in the table */ + movieTheater->collect[movieTheater->numTheaters] = temp; + movieTheater->numTheaters = movieTheater->numTheaters + 1; + scanf("%f", &temp); + } +} + +void update(tTheater *movieTheater) { + /* var definition */ + int i; + + /* iteration. We can use a for ... do iteration because we know the exact number of element of the table */ + for (i = 0; i < movieTheater->numTheaters; i++) { + movieTheater->collect[i] = movieTheater->collect[i] *1.20 ; + } +} + +void printTable(tTheater movieTheater) { + /* var definition */ + int i; + + /* iteration. We can use a for ... do iteration because we know the exact number of element of the table */ + for (i=0; i< movieTheater.numTheaters; i++) { + printf("%f ", movieTheater.collect[i]); + } +} + +int main(int argc, char** argv) { + tTheater santalo; + fillTable(&santalo); + printTable(santalo); + update(&santalo); + printTable(santalo); + return 0; +} +``` + +Comentarios: +- Hemos escrito un algoritmo completo que hemos estructurado con acciones donde cada acción hace una operación concreta sobre una tabla de valores de tipo real. +- Las acciones incluyen la inserción de elementos en la tabla y el control de cuántos se han insertado, un recorrido para aumentar la recaudación y otro recorrido para mostrar por el canal estándar los valores guardados en la tabla. +- En la acción de escritura, la tabla se pasa como parámetro solamente de entrada. Fijaos en que en C, en este caso, la notación utilizada para acceder a los campos de la tupla (record) es el punto (.). ## 16.5 Búsqueda de un elemento en una tabla + + ## 16.6 Ordenación de las tablas