diff --git a/fundamentos-programacion/PR3/README.md b/fundamentos-programacion/PR3/README.md index d532531..530fd87 100644 --- a/fundamentos-programacion/PR3/README.md +++ b/fundamentos-programacion/PR3/README.md @@ -566,37 +566,460 @@ Comentarios: ## 16.5 Búsqueda de un elemento en una tabla +Para realizar una búsqueda debemos hacer un recorrido de todos los elementos de la tabla, pero a diferencia del recorrido secuencial, en este caso, paramos cuando encontramos el elemento que buscamos. Por lo tanto la iteración debe ser con un bucle while y no con un for. +```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 + movieTheater: tTheater; + value: real; + position: integer; + end var + + fillTable(movieTheater); + value:= readReal(); + searchValue(movieTheater, value, position); + writeInteger(position); +end algorithm + +action fillTable(out movieTheater: tTheater); + var + i: integer; + temp: real; + end var + + {table initialization} + movieTheater.numTheaters:=0; + temp:= readReal(); {we read the first digit} + + {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 searchValue(in movieTheater: tTheater, in value: real, out position: integer) + var + i: integer; + found: boolean; + end var + + {variable initialization. i is set to 1 to start searching in the table at postion 1 and found to false to indicate that so far value has not been found. The out parameter position is set to -1 by default} + i:= 1; + found:= false; + position:= -1; + + {iteration while there still are elements in the table and the value has not been found} + while i≤ movieTheater.numTheaters and not found do + if movieTheater.collect[i] ≥ value then + found:= true; + else + i:=i + 1; + end if + end while + + if found then + position := i; + end if +end action +``` + +```c +#include +#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); /* read the first digit */ + + /* 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 searchValue(tTheater movieTheater, float value, int *position) { + /* var definition */ + int i; + bool found; + + /* variable initialization. i is set to 0 to start searching in the table at postion 0 and found to false to indicate that so far value has not been found. The out parameter position is set to -1 by default */ + i = 0; + found = false; + *position = -1; + + /* iteration while there still are elements in the table and the value has not been found */ + while (i < movieTheater.numTheaters && !found) { + if (movieTheater.collect[i] >= value) { + found = true; + } else { + i++; + } + } + + if (found) { + *position = i; + } +} + +int main(int argc, char** argv) { + tTheater movieTheater; + float value; + int position; + + fillTable(&movieTheater); + printf("%d", movieTheater.numTheaters); + scanf("%f", &value); + searchValue(movieTheater, value, &position); + printf("%d", position); + + return 0; +} + +``` + +Comentarios: +- Se inicializa el valor de la variable `position` a -1 para indicar que no se ha encontrado el valor buscado. +- Para buscar el elemento iteramos con el bucle while controlando si se encuentra el valor o no. Si se encuentra no llega al final de la tabla. No podemos usar un for ya que no sabemos en qué momento podemos encontrar el valor buscado. +- En el lenguaje algorítmico el índice empieza en 1 mientras que en C empieza en 0. +- El parámetro `position` es de salida, por eso se utiliza el caracter * delante del nombre del parámetro. ## 16.6 Ordenación de las tablas - ### 16.6.1 Inserción ordenada +Vamos a modificar en el ejemplo anterior la acción de lectura de las recaudaciones para que se mantenga la tabla siempre ordenada. + +```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 + i, j: integer; + found: boolean; + temp: real; + end var + + {table initialization} + movieTheater.numTheaters:=0; + temp:= readReal(); {we read the first digit} + + {iteration while the read number is not -1} + while temp ≠ END_SEQ do + {find the right location} + i:= 1; + found:= false; + + {search for the right location} + while i ≤ movieTheater.numTheaters and not found do + if movieTheater.collect[i] ≥ temp then + found:= true; + else + i:= i + 1; + end if + end while + + {all the values to the right of the position found must be moved to one position to the right} + if movieTheaters.numTheathers > 0 then + for j:= movieTheaters.numTheathers to i step -1 do + movieTheater.collect[j+1]:= movieTheater.collect[j]; + end for + end if + + {insert new value} + movieTheater.collect[i]:= temp; + movieTheater.numTheaters:= movieTheater.numTheaters + 1; + temp:= readReal(); + end while +end action +``` + +```c +#include +#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; + int i, j; + bool found; + + /* table initialization */ + movieTheater->numTheaters = 0; + scanf("%f", &temp); /* read the first digit */ + + /* iteration while the read number is not -1 */ + while (temp != END_SEQ) { + i = 0; + found = false; + + /* search for the right location */ + while (i < movieTheater->numTheaters && !found) { + if (movieTheater->collect[i] >= temp) { + found = true; + } else { + i++; + } + } + + /* move values to the right */ + if (movieTheater->numTheaters > 0) { + for (j = movieTheater->numTheaters; j >= i; j--) { + movieTheater->collect[j] = movieTheater->collect[j-1]; + } + } + + /* insert new value */ + movieTheater->collect[i] = temp; + movieTheater->numTheaters = movieTheater->numTheaters + 1; + scanf("%f", &temp); + } +} + +int main(int argc, char** argv) { + tTheater santalo; + int i; + + fillTable(&santalo); + + for (i = 0; i < santalo.numTheaters; i++) { + printf("%f ", santalo.collect[i]); + } + + return 0; +} +``` + +Comentarios: +- Para mantener la tabla ordenada cada vez que se inserte un valor nuevo, primnero es necesario buscar el lugar adecuado que le corresponde según los valores que ya hay en la tabla y el que queremos insertar. Para encontrarlo usamos una búsqueda, que corresponde al while más interno. +- Una vez encontrado el sitio correcto, es necesario desplazar hacia la derecha 1 casilla todos los elementos que quedan a la derecha del punto donde se debe insertar. Para hacerlo, usamos una iteración de tipo for, ya que savemos cuántos elementos se debe mover. +- En el algoritmo hemos uspuesto que en la secuencia de entrada nunca habrá más números de los permitidos. Si no se sabe con seguridad, sería necesario añadir al algoritmo un control para evitar que se intente insertar un elemento fuera del rango de la tabla. + ### 16.6.2 Algoritmo de ordenación +La ordenación de las tablas es un tema bastante extenso, vamos a ver uno fácil de entender, aunque no sea el más eficiente. + +Si la tabla tiene n elementos, el algoritmo consiste en iterar n veces de la siguiente manera: +1. La primera iteración es un recorrido por toda la tabla para encontrar el elemento menor. Cunado se identifica, se intercambian los elementos de la posición 1 y la posición del más pequeño, de tal manera que al acabar la primera iteración sabemos que el primer elemento de la tabla es el menor. +2. En la segunda iteración ya no hace falta recorrer toda la tabla, sino que podemos empezar en el segundo elemento y hacer el mismo proceso pero desde la posición 2. +3. En la tercer iteración se repite el procedimiento pero empezando en la posición 3. +4. Y así se repite el procedimiento hasta la última iteración. + +Ahora vamos a retomar el ejemplo anterior y rellenamos la tabla con las recaudaciones usando el algoritmo inicial y ordenando como la anterior metodología. + +```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); + sort(santalo); + + for i:= 1 to santalo.numTheaters do + writeReal(santalo.collect[i]); + end for +end algorithm + +action fillTable(out movieTheater: tTheater); + var + i: integer; + temp: real; + end var + + {table initialization} + movieTheater.numTheaters:=0; + temp:= readReal(); {we read the first digit} + + {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 sort(inout movieTHeater:tTheater) + var + i, j, posMin: integer; + aux: integer; + end var + + i:= 1; + while j ≤ movieTheater.numTheaters do + posMin:= i; + j:= i + 1; + while j ≤ movieTheater.numTheaters do + if movieTheater.collect[j] < movieTheater.collect[posMin] then + posMin:= j; + end if + j:= j + 1; + end while + + aux:= movieTheater.collect[posMin]; + movieTheater.collect[posMin]:= movieTheater.collect[i]; + movieTheater.collect[i]:= aux; + i:= i + 1; + 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 */ + int i; + float temp; + + /* table initialization */ + movieTheater->numTheaters = 0; + scanf("%f", &temp); /* read the first digit */ + + /* 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 sort(tTheater *movieTheater) { + /* var definition */ + int i, j, posMin; + float aux; + + i = 0; + while (i < movieTheater->numTheaters) { + posMin = i; + j = i + 1; + while (j < movieTheater->numTheaters) { + if (movieTheater->collect[j] < movieTheater->collect[posMin]) { + posMin = j; + } + j++; + } + + aux = movieTheater->collect[posMin]; + movieTheater->collect[posMin] = movieTheater->collect[i]; + movieTheater->collect[i] = aux; + i++; + } +} + +int main(int argc, char** argv) { + tTheater santalo; + int i; + + fillTable(&santalo); + sort(&santalo); + + for (i = 0; i < santalo.numTheaters; i++) { + printf("%f ", santalo.collect[i]); + } + + return 0; +} +``` + ### 16.6.3 Importancia del orden en las tablas + + #### 16.6.3.1 Ejemplo + + #### 16.6.3.2 Ejemplo + ## 16.7 Tabla de tipos estructurados + + ### 16.7.1 Tablas de tuplas + ### 16.7.2 Tabla de tablas + [Volver arriba](#pr-1)