Descarga la aplicación para disfrutar aún más
Vista previa del material en texto
PROGRAMACIÓN I-2019 Teoría – Ma. Virginia Ainchil1 TEMAS de la CLASE 1 2 3 4 TEORIA 9 Definición de tipo de dato Arreglo Declaración del tipo de dato Vector Operaciones frecuentes en el tipo Vector Ejercitación Estructura de datos ARREGLO Arreglos: Motivación Supongamos que un supermercado dispone de la información de sus 100 productos y desea informar los nombres de los productos cuyo precio supera el promedio de precios del supermercado. Pueden existir diferentes soluciones con los tipos de datos que hemos visto hasta ahora en el curso: ¿Cómo organizaría la información? ¿Cómo procesaría los datos para tener el promedio de los precios y compararlo con el precio de cada producto? 1000 Leche SanCor 100 20 1100 Yoghurt Sancor 200 23 5055 Detergente Ala 0 55 2400 Fideos Matarazzo 35 30 5250 Cerveza Quilmes 100 50 ATENCION!! Para los 100 productos, donde cada uno tiene 5 datos nos obliga a leer una vez 100 x 5 = 500 datos. Y luego otra vez 100 x 5 = 500 datos. En total se leen 1000 datos. a) Ingresar 2 veces el conjunto de datos. Se ingresan los datos para calcular el promedio de precios y luego volvemos a ingresar los mismos datos, comparando el precio promedio con el precio de cada producto. Arreglos: Motivación Código Marca Nombre Precio Stock 1000 Leche SanCor 100 20 1100 Yoghurt Sancor 200 23 5055 Detergente Ala 0 55 2400 Fideos Matarazzo 35 30 5250 Cerveza Quilmes 100 50 b) Usar tantas variables diferentes como productos existen. Es decir en cada variable guardamos un producto distinto a medida que se lee (en este caso necesitamos 100 variables diferentes). Luego calculamos el promedio y comparamos cada precio con el mismo. ATENCION!! Esta solución resulta mas compleja a medida que aumenta el número de productos ¿Por qué? 1000 Leche SanCor 100 20 1100 Yoghurt Sancor 200 23 5055 Detergente Ala 0 55 2400 Fideos Matarazzo 35 30 5250 Cerveza Quilmes 100 50 Arreglos: Motivación Código Marca Nombre Precio Stock A partir de la solución (b) resulta claro que sería conveniente tener una estructura que reúna a todos los productos bajo un único nombre y que a la vez permita diferenciar (y acceder) a los datos de cada uno. Para resolver estos problemas podemos usar una estructura de datos tipo ARREGLO. Arreglos: Motivación 1000 Leche SanCor 100 20 1100 Yoghurt Sancor 200 23 5055 Detergente Ala 0 55 2400 Fideos Matarazzo 35 30 5250 Cerveza Quilmes 100 50 Productos Productos [1] Productos [2] Productos [4] Productos [3] 1000 Leche SanCor 100 20 1100 Yoghurt Sancor 200 23 5055 Detergente Ala 0 55 2400 Fideos Matarazzo 35 30 5250 Cerveza Quilmes 100 50 Productos Un arreglo (ARRAY) es una estructura de datos que permite acceder a cada componente a través de una variable denominada índice, que indica la posición de la componente dentro de la estructura de datos. Indice Arreglos: Concepto Precisamente por ser estática, permite el acceso rápido a sus componentes a través de la variable índice ( que tiene que ser de tipo ordinal ) y que puede verse como el desplazamiento desde la posición inicial de comienzo de la estructura. Un Indice: vector Dos Indices: matriz Arreglos: Ejemplos 9 Arreglos: Recordemos clasificación… Numérico Carácter Lógico Tipos de Datos Simples Compuestos (def. por el usuario) Def. por el lenguaje Def. por el usuario Subrango String Registro Arreglo Estructurados Un tipo de dato Arreglo es una colección de elementos que se guardan consecutivamente en la memoria y se pueden referenciar a través de índices. Esta estructura de datos reúne las siguientes características: Todos los elementos son del mismo tipo de datos, por eso es una estructura de datos homogénea. Los elementos o componentes pueden recuperarse en cualquier orden, indicando simplemente su posición, por eso es una estructura de datos de acceso directo. Como el acceso se hace a través del índice se la denomina también indexada. La memoria ocupada durante la ejecución del programa es fija, por eso se dice que es una estructura de datos estática. Dado que cada elemento tiene un elemento que le precede y uno que le sigue, esta estructura se denomina lineal. Arreglos: Definición En la memoria habrá 100 casilleros seguidos conteniendo cada uno los datos de los productos. La cantidad total de memoria depende de la cantidad de componentes y del tipo de dato de cada uno. En este caso serán 100 componentes de 40 bytes cada una 4000 bytes. Productos Si tenemos los 100 productos del supermercado Arreglos: Tipo Vector 1000 Leche SanCor 100 20 1100 Yoghurt Sancor 200 23 5055 Detergente Ala 0 55 2400 Fideos Matarazzo 35 30 5250 Cerveza Quilmes 100 50 Productos 1000 Leche SanCor 100 20 1100 Yoghurt Sancor 200 23 5055 Detergente Ala 0 55 2400 Fideos Matarazzo 35 30 5250 Cerveza Quilmes 100 50 y los almacenamos en un vector llamado PRODUCTOS de esta forma: Cuando se trabaja con vectores hay que tener en cuenta que: El valor 3 es la posición ó ubicación dentro de la estructura de datos (índice). Los datos del registro son el contenido de esa posición o ubicación. Productos 1000 Leche SanCor 100 20 1100 Yoghurt Sancor 200 23 5055 Detergente Ala 0 55 2400 Fideos Matarazzo 35 30 5250 Cerveza Quilmes 100 50 Productos [3] 5055 Detergente Ala 0 55 31 2 100 Tipo Vector: Posición y contenido Se puede decir que: La variable Productos tiene asociada un área de memoria fija consecutiva que es el lugar donde se almacenará la información de los productos. La variable Productos ocupa 100 posiciones de memoria como lo indica su declaración. Declaración del Tipo Vector en Pascal Type cadena15 = string [15]; producto= Record codigo: integer; nombre: cadena15; marca: cadena15; stock; integer; precio: real End; vectorProductos=array [1..100] of producto; Var Productos : vectorProductos; Vector = Array [ indice ] of tipo_elementos; Es posible indexar los elementos por un índice que corresponde a cualquier tipo ordinal: • Entero • Carácter • Subrango Los elementos de un arreglo pueden pertenecer a cualquier tipo de datos de alocación estática: • Entero, Real, Lógico, Carácter • String • Registros • Otro arreglo ¿Por qué? ¿Por qué? Declaración del Tipo Vector en Pascal Declaraciones en Pascal - Ejemplos Const limite=1000; Type periodo = 2000..2015; AñosAutos = Array [periodo] of integer; Cajas = Array [ ‘A’ .. ‘D’ ] of real; numeros = array [1..limite] of integer; cadena15 = string [15]; fecha = record día: 1..31; mes: 1..12; año: 1900..2100; end; articulo = Record codigo: integer; ident: cadena15; marca: cadena15; fechaVenc:fecha; Precio: real End; todoslosarticulos= Array [1..100] of articulo; Var N: numeros; {1000 elem entero} Autos: añosAutos; {16 elem entero} negocio: todoslosarticulos; {100 elem tipo articulo} TotalporCaja: cajas; {4 elem real} Arreglos: Operaciones del tipo vector Asignación de contenido a un elemento Lectura / Escritura Recorridos Cargar datos en un vector Agregar elementos al final Insertar elementos Borrar elementos Buscar un elemento O p e ra ci ó n : A si g n a ci ó n d e c o n te n id o a u n e le m e n to d e l v e ct o r Const limite=1000; Type numeros = array [1..limite] of integer; cadena15 = string [15]; producto= Record codigo: integer; nombre: cadena15; marca: cadena15; stock; integer; precio: real End; vectorProductos = array [1..100] of producto; Var N: números; i:integer; Productos : vectorProductos; Begin N[6]:= ‘a’; N[‘b’] := 12; i:= 1 productos[120].precio := 25.5; productos[i].stock := 23.5; …….. End. Type rangoCajas = ‘A’..’D’; Cajas = Array [ rangoCajas ] of real; cadena15 = string [15]; producto= Record codigo: integer; nombre: cadena15; marca: cadena15; stock; integer; precio: real End; vectorProductos = array [1..100] of producto; Var TotalporCaja: Cajas; Productos: vectorProductos; i : integer; j: rangoCajas; Si se necesita inicializar el stock en 0 de todos los elementos del vector de Productos o el total facturdo por cada caja, se puede : O p e ra ci ó n : A si g n a ci ó n d e c o n te n id o a u n e le m e n to d e l v e ct o r En productos, el valor 0 se asigna al campo stock de cada elemento. En TotalporCaja, el valor 0 se asigna a cada uno de los elementos del vector Begin …….. for i:= 1 to 100 do productos[i].stock:= 0; for j:= ‘A’ to ‘D’ do TotalporCaja[i]:= 0; …….. End. O p e ra ci ó n : A si g n a ci ó n d e c o n te n id o a u n e le m e n to d e l v e ct o r Type cadena15 = string [15]; producto= Record codigo: integer; nombre: cadena15; marca: cadena15; stock; integer; precio: real End; vectorProductos = array [1..100] of producto; Var Productos : vectorProductos; i : integer; suma: integer; Begin ….. productos[1].precio:= productos[1].precio + 10; productos[3].precio:= 100 + 10; productos[5].precio:= productos[1].precio + productos[3].precio; suma := 0; for i:= 1 to 100 do suma := suma + productos[i].stock; …….. End. Const limite=1000; Type índice = 1..limite; numeros = array [indice] of integer; cadena15 = string [15]; producto= Record codigo: integer; nombre: cadena15; marca: cadena15; stock; integer; precio: real End; vectorProductos=array [1..100] of producto; O p e ra ci ó n : L e ct u ra y e sc ri tu ra d e l o s e le m e n to s d e u n v e ct o r ¿En qué variable queda el resultado de la lectura? ¿Qué muestra el write? Procedure mostrarProducto (prod: producto); begin Writeln (prod.codigo); Writeln(prod.nombre); Writeln (prod.marca); Writeln (prod.stock); Writeln (prod.precio); end; Procedure LeerProducto (Var prod: producto); begin Readln (prod.codigo); Readln (prod.nombre); Readln (prod.marca); Readln (prod.stock); Readln (prod.precio); end; Var N:números; Productos : vectorProductos; i : integer; k:índice; Begin for k:= 1 to limite do readln (N[k]); for k:= 1 to limite do writeln (N[k]); for i:= 1 to 100 do leerProducto (Productos[i]); for i:= 1 to 100 do MostrarProducto (Productos[i]); …….. End. Vector : Operación de Recorrido La operación de Recorrido en un vector consiste en recorrer el vector de manera total o parcial, para realizar algún proceso sobre sus elementos. La operación de Recorrido Total, implica analizar todos los elementos del vector, lo que lleva a recorrer completamente la estructura. La operación de Recorrido Parcial, implica analizar los elementos del vector, hasta encontrar aquel que cumple con lo pedido. Puede ocurrir que se recorra todo el vector. ¿Qué estructuras de control conviene utilizar en cada caso? ¿Ejemplos? Vector : Ejemplo de Recorrido Total Por ejemplo, si se necesita conocer la cantidad total de productos del supermercado, habrá que realizar un recorrido total que acumule los stocks de cada producto. Type cadena15 = string [15]; producto= Record codigo: integer; nombre: cadena15; marca: cadena15; stock; integer; precio: real End; vectorProductos=array [1..100] of producto; Var productos: vectorProductos; st_total:integer; i: integer; begin {el vector contiene datos de 100 productos} st_total:= 0; {recorrido total del vector} For i := 1 to 100 do st_total := st_total + productos[i].stock; writeln ( ´El stok total es: ´, st_total); end. Vector : Ejemplo de Recorrido parcial Program stock0; Type cadena15 = string [15]; producto= Record codigo: integer; nombre: cadena15; marca: cadena15; stock; integer; precio: real End; vectorProductos = array [1..100] of producto; Var productos: vectorProductos; i:integer; begin {el vector contiene datos de 100 productos} i := 1; while (productos[i].stock <> 0) do i:= i+1; writeln(´Producto: ´, productos[i].nombre); end. Por ejemplo, se quiere conocer el nombre del primer producto con stock en 0, (seguro existe). Tendremos que recorrer el vector de productos hasta encontrar el primer producto con stock en 0. ¿Qué ocurre si en el ejemplo anterior se cambia la precondición y el producto con stock en 0 podría no existir? V e ct o r : E je m p lo d e R e co rr id o p a rc ia l Program stock0; Type cadena15 = string [15]; producto= Record codigo: integer; nombre: cadena15; marca: cadena15; stock; integer; precio: real End; vectorProductos = array [1..100] of producto; Var productos: vectorProductos; i:integer; begin {el vector contiene datos de 100 productos} i := 1; while (productos[i].stock <> 0) do i:= i+1; writeln (´El product es:’, productos[i].nombre); end. While ( i <= 100) and ( productos[i].stock<>0) do If i<=100 then writeln (‘Producto:’, productos[i].nombre) else write (‘No existe’); End: Vector: dimensiones Física y lógica Cuando se trabaja con vectores se deben hacer consideraciones importantes acerca de algunos aspectos: Dimensión Física del vector se especifica en el momento de la declaración y determina su ocupación de memoria. La cantidad de memoria no variará durante la ejecución del programa. Dimensión Lógica del vector se determina cuando se cargan contenidos a los elementos del arreglo. Indica la cantidad de posiciones de memoria ocupadas con contenidos cargados desde la posición inicial en forma consecutiva. ¿Por qué? Vector: parámetros... ¿Qué parámetros deberían recibir y devolver los módulos que tratan con arreglos? ¿De qué tipo conviene que sean los parámetros relacionados con arreglos? Vector: Cargar datos en un vector Consideraciones dimF : dimensión física del vector (tamaño especificado en la declaración del vector) dimL : cantidad de elementos en el vector (dimensión lógica). Se pide cargar valores enteros en un vector de a lo sumo 1000 elementos. La lectura de los valores finaliza con el valor 99. Const DimF = 1000; Type vector = Array [ 1..DimF] of integer; Procedure CARGAR ( var num: vector; var dimL: integer ); var dato : integer; begin dimL := 0; read (dato); while (dato <> 99) and ( dimL < dimF ) do begin dimL := dimL + 1; num [dimL] := dato; read (dato) end; End; Supongamos que se leen los valores: 5, 20, 13, 18, 100, 25 y 99 num 5 20 13 18 100 25 1 10002 …………… dimL -> 6 ………… Vector: Cargar datos en un vector dimL : cantidad de elementos en el vector (dimensión lógica). dimF : dimensión física del vector (tamaño especificado en la declaración del vector) espacio suficiente: Debe verificarse que dimL < dimF (dimensión lógica < dimensión física) El elemento a agregar ocupa la posición dimL+1. Luego de la operación la cantidad de elementos es dimL+1. Vector: Agregar un elemento al final La operación de Agregar un elemento en un vector consiste en incorporar el elemento a continuación del último ingresado, es decir, en la posición siguiente a la indicada en la dimensión lógica. Esta operación debe verificar que haya lugar en la estructura, es decir que la dimensión lógica sea menor que la dimensión física. CONSIDERACIONES Procedure AGREGAR (var v: vector; var dimL:integer; elemento: integer; var exito : boolean); Begin {verificar espacio suficiente} If (dimL < dimF) then begin dimL:= dimL+1; {actualizar cantidad de elementos} v [dimL]:= elemento; exito := true end else exito := false; end; Vector: Agregar un elemento al final Vector: Insertar un elemento CONSIDERACIONES dimF : dimensión física del vector (tamaño especificado en la declaración del vector). dimL: cantidad de elementos en el vector. De ser posible la operación, la cantidad de elementos será dimL+1. La operación de Insertar un elemento en un vector consiste en incorporar el elemento en una posición determinada o de acuerdo a un orden impuesto a sus datos. Esta operación también tiene que verificar que haya lugar en la estructura, es decir que la dimensión lógica sea menor que la dimensiónfísica. Insertar un elemento manteniendo un orden interno determinado Insertar un elemento en una posición determinada 5 20 13 18 100 25 …………… 10006541 2 3 Posición 4 Elemento 33 5 20 13 18 100 25 …………… 10006541 2 3 33 7 1 2 Vector: Insertar un elemento 2. Verificar espacio en el vector 5. Aumentar la dimensión lógica 1. Verificar la posición a insertar 3. Abrir el vector (a partir de la dimensión lógica) 4. Asignar el valor 24 5 8 17 30 23 ? ? ? ? 1 64 75 …8 dimF2 3 26 elemento Pos =2 Dimensión lógica = 6 23301785 Dimensión lógica = 7 Supongamos que se quiere insertar el valor 26 en la posición 2 de un vector de valores enteros… Insertar un elemento en una posición determinada Esta operación también tiene que verificar que la posición sea válida. 2. Verificar espacio en el vector 5. Aumentar la dimensión lógica 1. Verificar la posición a insertar 3. Abrir el vector (a partir de la dimensión lógica) 4. Asignar el valor Parámetros de la operación: v: arreglo a trabajar dimL: cantidad de elementos Elemento: dato a insertar Pos: posición donde insertar exito: resultado operación Procedure INSERTARPOS(var v: vector; var dimL: integer; elemento: integer; pos: integer; var exito: boolean ); var i : integer; Begin if (dimF > dimL) and ((pos>=1) and (pos<= dimL)) then begin exito := true; for i := dimL downto pos do v [ i + 1 ] := v [ i ] ; v [pos] := elemento; dimL := dimL + 1; end else exito := false; end; Asignar el valor Aumentar la dimensión Insertar un elemento en una posición determinada Consideración dimL : cantidad de elementos en el vector. Vector: Borrar un elemento La operación de Borrar un elemento en un vector consiste en eliminar un elemento determinado o bien eliminar un elemento que ocupa una posición determinada. En el caso de borrar un elemento en una posición determinada, se debe verificar que la posición sea válida. Borrar un elemento determinado del vector Borrar un elemento en una posición determinada Posición 3 5 20 13 18 100 25 …………… 10006541 2 3 33 7 1 2 5 20 18 100 25 …………… 10006541 2 3 33 ¿Dimensión lógica? Vector: Borrar un elemento 1. Validar la posición a borrar 3. Disminuir la dimensión lógica 2. Desplazar elementos (a partir de la posición siguiente) Procedure BORRARPOS (var v: vector; var dimL: integer; pos: posicion; var exito: boolean ); var j: integer; begin if (pos >=1 and pos <= dimL) then begin exito := true for j:= pos to dimL-1 do v [ j ] := v [ j + 1 ] ; dimL := dimL - 1 ; end else exito := false; End; Parámetros de la operación: Num: vector a trabajar dimL: cantidad de elementos Pos: posición a borrar exito: resultado operación Disminuir la dimensión lógica Vector: Borrar un elemento en una posición Ejercitación 1. Se lee una sucesión de 100 nombres y notas de alumnos. Informar los nombres y notas de los alumnos que superan el promedio del grupo. Leer, Guardar y Sumar todas las notas Inicializar suma de notas Repetir 100 leer datos de alumno guardar datos del alumno actualizar suma de notas -Leer, Guardar y Sumar todas las notas - Calcular promedio -Recorrer y Comparar cada nota con el promedio Recorrer y Comparar cada nota con el promedio Repetir 100 acceder a los datos del alumno si nota > promedio entonces informar nombre 1. Se lee una sucesión de 100 nombres y notas de alumnos. Informar los nombres y notas de los alumnos que superan el promedio del grupo. Program ejemplo1; const total= 100; {dimensión física} type str20 := string [20]; alumno = record nombre : str20; nota : real; end; ListaDatos = array [1..total] of alumno; {implementación LeerGuardarSumar} {implementación RecorreryComparar} var datos: ListaDatos; suma, promedio : Real; Begin LeerGuardarSumar(datos, suma); promedio := suma/total; RecorreryComparar (datos, promedio); End. procedure LeerGuardarSumar (var dat: ListaDatos; var sum : Real); Procedure leerAlumno (var alu:alumno); begin read (alu.nombre); read (alu.nota); end; var j : integer; a:alumno; begin sum := 0; for j := 1 to total do begin leerAlumno (a); dat[j]:= a; sum := sum + dat[j].nota; end end; const total= 100; {dimensión física} type str20 = string [20]; alumno = record nombre : str20; nota : real; end; ListaDatos=array [1..total] of alumno; Leer, Guardar y Sumar todas las notas Inicializar suma de notas Repetir 100 leer datos de alumno guardar datos del alumno actualizar suma de notas Recorrer y Comparar cada nota con el promedio Repetir 100 acceder a los datos del alumno si nota > promedio entonces informar nombre Procedure RecorreryComparar (dat: ListaDatos; prom: real); var i: integer; begin for i := 1 to total do if (dat[i].nota > prom) then Writeln (dat[i].nombre, ´ ´, dat[i].nota ) End. const total= 100; {dimensión física} type str20 := string [20]; alumno = record nombre : str20; nota : real; end; ListaDatos=array [1..total] of alumno; - Leer, Guardar y Sumar todas las notas - Calcular promedio - Recorrer y Comparar cada nota con el promedio Recorrer y Comparar cada nota con el promedio Repetir cantidad alumnos guardada acceder a los datos del alumno si nota > promedio entonces informar nombre 2. Se lee una sucesión nombres y notas de alumnos que finaliza con nombre “Fulano”. Informar los nombres y notas de los alumnos que superan el promedio del grupo. Nota: como máximo se pueden ingresar 100 alumnos. Leer, Guardar y Sumar todas las notas Inicializar suma de notas Leer datos de alumno Mientras (haya lugar) y (no ingrese “Fulano” ) guardar en el vector actualizar suma de notas leer datos de alumno Ejercitación 2. Se lee una sucesión nombres y notas de alumnos que finaliza con nombre “Fulano”. Informar los nombres y notas de los alumnos que superan el promedio del grupo. Nota: como máximo se pueden ingresar 100 alumnos. - Leer, Guardar y Sumar todas las notas - Calcular promedio - Recorrer y Comparar cada nota con el promedio Program ejemplo2; const total= 100; {dimensión física} type str20 := string [20]; alumno = record nombre : str20; nota : real; end; rango = 0.. total; ListaDatos = array [1..total] of alumno; {implementación LeerGuardarSumar} {implementación RecorreryComparar} var datos: ListaDatos; dim: rango; suma, promedio : Real; Begin LeerGuardarSumar(datos, dim, suma); if dim <>0 then begin promedio := suma/dim; RecorreryComparar(datos, dim, promedio) end; End. const total= 100; {dimensión física} type str20 := string [20]; alumno = record nombre : str20; nota : real; end; rango = 0.. total; ListaDatos=array [1..total] of alumno; Leer, Guardar y Sumar todas las notas Inicializar suma de notas Leer datos de alumno Mientras (haya lugar) y (no ingrese “Fulano” ) guardar en el vector actualizar suma de notas leer datos de alumno procedure LeerGuardarSumar (var dat:ListaDatos; var dim: rango; var sum : Real); Procedure leerAlumno (var alu:alumnos); begin read (alu.nombre); if (alu.nombre <> ´Fulano´) then read (alu.nota); end; var a : alumno; begin sum := 0; dim := 0; {dimensión lógica} leerAlumno (a); while (dim < 100) and (a.nombre <> ´Fulano´) do begin dim := dim + 1; dat[dim]:= a; sum := sum + dat[dim].nota; leerAlumno (a); end end; Procedure RecorreryComparar (dat: ListaDatos; dim:rango; prom: real); var i: integer; begin for i := 1 to dim do if (dat[i].nota > prom) then Writeln (dat[i].nombre, ´ ´, dat[i].nota ) End. Recorrer y Comparar cada nota con el promedio Repetir cantidad alumnos guardada acceder a los datos del alumno si nota > promedio entonces informar nombre const total= 100; {dimensión física} type str20 := string [20]; alumno = record nombre : str20; nota : real; end; rango = 0.. total; ListaDatos = array [1..total] of alumno; 4. Se desea simular la venta de pasajes de micro para Mar del Plata, el día 25 de mayo de 2015 a las 12 Hs. Se sabe que el micro dispone de 45 asientos(ventanilla/pasillo). El pasajero solicita un asiento determinado y se registrará la venta solamente si está libre y en ese caso también se guardará el DNI del pasajero. De lo contrario indicar que la venta no se pudo realizar. 5. Se desea simular la atención de la Oficina de Tránsito de la Municipalidad que diariamente entrega hasta 50 números para obtener la Licencia de Conductor de 7 a 8Hs. Para ello, se requiere guardar el DNI y Nombre y Apellido de la persona a la que se le entrega el número. Analicemos la declaración de tipos y variables ¿Dimensión Física? ¿Dimensión Lógica? 3. Se lee una secuencia de letras minúsculas que termina en punto. Informar la cantidad de veces que aparece cada letra. Ejercitación Dada una colección de elementos, es posible extraer dos tipos de información: Información relativa al conjunto de datos de dicha colección. Información detallada de algún ítem en particular. ¿Por qué es importante una operación de búsqueda? Arreglos: Operación de Búsqueda El proceso de ubicar información particular en una colección de datos es conocido como método de búsqueda. Los datos se presenten sin ningún orden Los datos se presenten ordenados por algún criterio En el vector puede darse que: Arreglos: Operación de Búsqueda En todos los casos los métodos de búsqueda que trabajaremos, consisten en buscar un dato que tiene una propiedad particular, y en caso de encontrarlo retornar alguna información relacionada con el ítem, por ejemplo, su posición. Métodos de Búsqueda Lineal o Secuencial Binaria o Dicotómica Arreglos: Operación de Búsqueda 24 12 5 33 0 89 -5 63 8 45 X= 89 La búsqueda comienza desde el principio y se avanza por la estructura de manera secuencial, uno a uno. Operación de Búsqueda Lineal o secuencial (elementos sin orden) La solución debería recorrer el vector y detenerse en caso de encontrar el elemento X. Buscar (Recibe el vector donde buscar, el elemento a buscar, la dimensión lógica y devuelve la posición donde se encontró) Ubicarse al principio del vector Mientras (no llegue al final del vector) y (no encuentre el elemento) avanzar una posición en el vector Al salir del mientras se debe evaluar por cual de las condiciones finalizó 24 12 5 33 0 89 -5 63 8 45 X= 89 Operación de Búsqueda Lineal o secuencial (elementos sin orden) Const DimF = ... {máxima longitud del vector} Type TipoElem = ... {tipo de datos del vector } Indice = 0.. DimF; vector = Array [ 1..DimF] of TipoElem; Consideremos la siguiente declaración genérica: Operación de Búsqueda Lineal o secuencial (elementos sin orden) Operación de Búsqueda Lineal o secuencial (elementos sin orden) Const DimF = ... Type Indice = 0.. DimF; vector= Array [ 1..DimF] of integer; Buscar (Recibe el vector donde buscar, el elemento a buscar, la dimensión lógica y devuelve la posición donde se encontró) Ubicarse al principio del vector Mientras (no llegue al final del vector) y (no encuentre el elemento) avanzar una posición en el vector Al salir del mientras se debe evaluar por cual de las condiciones finalizó Function BuscarPosElem (x:integer;v:vector;dimL: Indice) : Indice; var pos:Indice; Begin pos:=1; while (pos <= dimL) and (x <> v[pos]) do pos:=pos+1; if (pos > dimL) then pos:=0; BuscarPosElem := pos; end; Características de la Búsqueda Lineal o Secuencial Se aplica cuando los elementos no tienen orden. Requiere excesivo consumo de tiempo en la localización del elemento. Número medio de comparaciones (dimL + 1) /2 Es ineficiente a medida que el tamaño del arreglo crece. Operación de Borrado de un elemento Recordemos que la operación de Borrar un elemento en un vector admite dos posibilidades: Borrar un elemento determinado del vector Opción 2 Borrar un elemento en una posición determinada Opción 1 Buscar la posición del elemento a borrar Borrar el elemento Esta operación requiere primero buscar el elemento y luego borrarlo Const DimF = ... Type Indice = 0.. DimF; vector = Array [ 1..DimF] of integer; Operación de Borrado de un elemento Si el elemento está entonces var pos: indice; begin pos:= BuscarPosElem (elem, v, dimL); if pos <> 0 then begin BorrarElemPosModif (v, dimL, pos); éxito:= true end else éxito:= False; end; Procedure BorrarElem (var v: vector; var dimL: indice; elem : integer; var exito: boolean); O p er ac ió n d e B o rr ad o d e u n e le m e n to var pos: indice; begin pos:= BuscarPosElem (elem, v, dimL); if pos <> 0 then begin BorrarElemPosModif (v, dimL, pos); éxito:= true end else éxito:= False; end; Function BuscarPosElem ( x: integer; v:vector; dimL: Indice) : Indice; var pos:Indice; Begin pos:=1; while (pos <= dimL) and (x <> v[pos]) do pos:=pos+1; if (pos > dimL) then pos:=0; BuscarPosElem := pos; end; Procedure BorrarElemPosModif (var v:vector; var dimL:integer; pos:Indice); begin end; Const DimF = ... Type Indice = 0.. DimF; vector = Array [ 1..DimF] of integer; Procedure BorrarElem (var v: vector; var dimL: indice; elem : integer; var exito: boolean); O p er ac ió n d e B o rr ad o d e u n e le m e n to Const DimF = ... Type Indice = 0.. DimF; vector = Array [ 1..DimF] of integer; Procedure BorrarElemPos (var v:vector; var dimL:integer; pos:Indice; var exito:boolean ); var j: integer; begin if (pos >=1 and pos <= dimL) then begin exito := true for j:= pos to dimL-1 do v [ j ] := v [ j + 1 ] ; dimL := dimL - 1 ; end else exito := false; end; Procedure BorrarElemPosModif (var v:vector; var dimL:integer; pos:Indice); var j: integer; begin for j:= pos to dimL-1 do v [ j ] := v [ j + 1 ] ; dimL := dimL - 1 ; end; O p er ac ió n d e B o rr ad o d e u n e le m e n to var pos: indice; begin pos:= BuscarPosElem (elem, v, dimL); if pos <> 0 then begin BorrarElemPosModif (v, dimL, pos); éxito:= true end else éxito:= False; end; Function BuscarPosElem ( x: integer; v:vector; dimL: Indice) : Indice; var pos:Indice; Begin pos:=1; while (pos <= dimL) and (x <> v[pos]) do pos:=pos+1; if (pos > dimL) then pos:=0; BuscarPosElem := pos; end; Procedure BorrarElem (var v: vector; var dimL: indice; elem : integer; var exito: boolean); Procedure BorrarElemPosModif (var v:vector; var dimL:integer; pos:Indice); var j: integer; begin for j:= pos to dimL-1 do v [ j ] := v [ j + 1 ] ; dimL := dimL - 1 ; end; Analicemos cada método… Operación de Búsqueda en Arreglos Ordenados 12 15 23 33 49 89 95 163 241 1103 X= 89 Método 1: Se recorre el vector hasta encontrar el número buscado o hasta encontrar uno mayor que él. Método 2: Acceder a los elementos del vector de una manera mas “eficiente”… Métodos posibles: Búsqueda en Arreglos Ordenados Método 1: Secuencial Optimizado. Se aplica cuando los elementos tienen orden. La búsqueda comienza desde el principio y se avanza por la estructura de manera secuencial y de a uno hasta que encuentro el número buscado o hasta que encuentro uno mayor . 12 15 23 33 49 89 95 163 241 1103 X= 89 Búsqueda en Arreglos Ordenados Método 1: Secuencial Optimizado. Módulo Buscar (el elemento a buscar, el vector donde buscar, la dimensión lógica y devuelve la posición donde se encontró) Ubicarse al principio del vector Mientras (no llegue al final del vector) y (el elemento a buscar sea mayor que el elemento observado) avanzar una posición en el vector Al salir del mientras se debe evaluar por cual de las condiciones finalizó 12 15 23 33 49 89 95 163 241 1103 X= 89 Const DimF=... Type Indice = 0.. DimF; vector = Array [ 1..DimF] of integer; Function BuscoPosElemOrd (x: integer; v:Vector; dimL: Indice): Indice; var pos : Indice; begin pos:=1; while (pos <= dimL) and (x > v[pos]) do pos:=pos+1; if ( pos > dimL ) or (x < v [pos]) then pos:=0; BuscoPosElemOrd:= pos; end; Búsqueda en Arreglos Ordenados Método 1: Secuencial Optimizado. Módulo Buscar (el elemento a buscar, elvector donde buscar, la dimensión lógica y devuelve la posición donde se encontró) Ubicarse al principio del vector Mientras (no llegue al final del vector) y (el elemento a buscar sea mayor que el elemento observado) avanzar una posición en el vector Al salir del mientras se debe evaluar por cual de las condiciones finalizó Operación Insertar un elemento en un vector Recordemos que la operación de Insertar un elemento en un vector admite dos posibilidades: Insertar un elemento en una posición determinada Opción 1 Insertar un elemento manteniendo un orden interno determinado Opción 2 Verificar espacio en el vector Determinar posición donde se insertara Insertar elemento en la posición determinada Esta operación requiere verificar el espacio disponible, buscar la posición correspondiente manteniendo el orden y luego insertar el elemento en el vector Operación Insertar un elemento en un vector ordenado Const DimF = ... Type Indice = 0.. DimF; vector = Array [ 1..DimF] of integer; Procedure InsertarElemOrd (var v: vector; var dimL: indice; elem : TipoElem; var exito: boolean); var pos: indice; begin if (dimL < dimF) then begin pos:= DeterminarPosicion (elem, v, dimL); Insertar (v, dimL, pos, elem); exito := true end else exito := false; end; Function BuscoPosElemOrd (x: integer; v:Vector; dimL: Indice): Indice; var pos : Indice; begin pos:=1; while (pos <= dimL) and (x > v[pos]) do pos:=pos+1; if ( pos > dimL ) or (x < v [pos]) then pos:=0; BuscoPosElemOrd:= pos; end; Function DeterminarPosicion ( x: integer; v:Vector; dimL: Indice): Indice; var pos : Indice; begin pos:=1; while (pos<=dimL) and (x > v[pos]) do pos:=pos+1; DeterminarPosicion:= pos; end; A d ap ta m o s “B u sc o Po sE le m O rd ” p ar a es cr ib ir “D et er m in ar Po si ci o n ” Const DimF = ... Type Indice = 0.. DimF; vector = Array [ 1..DimF] of integer; Procedure INSERTARPOS(var v: vector; var dimL: integer; elemento: integer; pos: integer; var exito: boolean ); var i : integer; Begin if (dimF > dimL) and ((pos>=1) and (pos<= dimL)) then begin exito := true; for i := dimL downto pos do v [ i + 1 ] := v [ i ] ; v [pos] := elemento; dimL := dimL + 1; end else exito := false; end; Procedure Insertar (var v:vector; var dimL:Indice; pos: Indice; elem:integer); var j: indice; begin for j:= dimL downto pos do v [ j +1 ] := v [ j ] ; v [ pos ] := elem; dimL := dimL + 1; End; A d ap ta m o s “I n se rt ar Po s” p ar a es cr ib ir “ In se rt ar ” Const DimF = ... Type Indice = 0.. DimF; vector = Array [ 1..DimF] of integer; O p er ac ió n In se rt ar u n e le m en to e n u n v ec to r o rd en ad o Procedure InsertarElemOrd (var v: vector; var dimL: indice; elem : TipoElem; var exito: boolean); Function DeterminarPosicion ( x: integer; v:Vector; dimL: Indice): Indice; var pos : Indice; begin pos:=1; while (pos<=dimL) and (x > v[pos]) do pos:=pos+1; DeterminarPosicion:= pos; end; Procedure Insertar (var v:vector; var dimL:Indice; pos: Indice; elem:integer); var j: indice; begin for j:= dimL downto pos do v [ j +1 ] := v [ j ] ; v [ pos ] := elem; dimL := dimL + 1; End; var pos: indice; begin if (dimL < dimF) then begin pos:= DeterminarPosicion (elem, v, dimL); Insertar (v, dimL, pos, elem); exito := true end else exito := false; end; Const DimF = ... {máxima longitud del vector} Type Indice = 0.. DimF; vector = Array [ 1..DimF] of integer; Se aplica cuando los elementos tienen orden. Se compara el valor buscado (x) con el ubicado en el medio del vector (a): Si el elemento ubicado al medio del vector es igual a x, entonces la búsqueda termina. Si no es el valor buscado, debería quedarse con la mitad del vector que conviene, para seguir la búsqueda. Este paso se repite tantas veces hasta que se acaba el vector o encuentro el valor. Búsqueda en Arreglos Ordenados: Método 2 – Búsqueda Dicotómica. Elemento buscado X= 89 a[medio]= a[5] = 49 Dado que 89 > 49, se trabajará con el “subvector” del medio al final a 12 15 23 33 49 89 95 163 241 Se calcula la posición del medio del vector original Si Búsqueda en Arreglos Ordenados: Método 2 – Búsqueda Dicotómica. a[medio]= a[7] = 95 Dado que 89 < 95, trabajo con el “subvector” del principio al medio 12 15 23 33 49 89 95 163 241 a Elemento buscado X= 89 Se descarta la primera parte Se calcula la posición del medio del “subarreglo” delimitado por: si Búsqueda en Arreglos Ordenados: Método 2 – Búsqueda Dicotómica. a a[medio]= a[6] = 89 89 = 89 se encontró el elemento!!! 12 15 23 33 49 89 95 163 241 Elemento buscado X= 89 Se descarta la “segunda” parte del ”subarreglo” (de 7 a 9) Se calcula la posición del medio del “subarreglo” delimitado por: si Búsqueda en Arreglos Ordenados: Método 2 – Búsqueda Dicotómica. Cada vez que se toma la mitad del arreglo, se va disminuyendo el tamaño del mismo. El proceso termina cuando encuentro el elemento, o cuando el vector se hace tan pequeño que no quedan mas elementos, y por lo tanto se puede deducir que el elemento no se encuentra en el vector. Analicemos ¿Qué ocurre cuando el elemento buscado no está en el vector? Observaciones: Búsqueda en Arreglos Ordenados: Método 2 – Búsqueda Dicotómica. Búsqueda en Arreglos Ordenados: Método 2 – Búsqueda Dicotómica. Procedure BusquedaBin ( var v: Vector; var j: Indice; dimL: Indice, x : TipoElem) ; Var pri, ult, medio : Indice ; Begin j :=0 ; pri:= 1 ; ult:= dimL; medio := (pri + ult ) div 2 ; While ( pri < = ult ) and ( x <> v [medio]) do begin If ( x < v [ medio ] ) then ult:= medio -1 ; else pri:= medio+1 ; medio := ( pri + ult ) div 2 ; end ; If pri < = ult Then j := medio Else j := 0 ; End ; Características de la Búsqueda Dicotómica Se aplica cuando los elementos tienen orden. Caso contrario debería ordenarse el vector previamente. Número medio de comparaciones (1+log2(dimL+1))/2. Cuando dimL crece el número medio de comparaciones es log2(dimL+1)/2. Eficiencia de la Busqueda secuencial y dicotómica busqueda secuencial Busqueda dicotómica número medio de comparaciones Número máximo de comparaciones N localizado no localizado Localizado no localizado 7 4 7 3 3 100 50 100 7 7 1.000 500 1.000 10 10 1.000.000 500.000 1.000.000 20 20 Ejercitación Una farmacia requiere el procesamiento de sus medicamentos. De cada medicamento se conoce su código, nombre, laboratorio, componente principal, stock y precio unitario. El procesamiento finaliza con el código -1 y se sabe que a lo sumo existen 1000 medicamentos y se ingresan ordenados por código. Se pide: a. Generar la estructura de datos que almacene los medicamentos. b. Simular un proceso de venta en el que se ingresa el código de medicamento y la cantidad que se vende. Se pide calcular el monto total recaudado por las ventas. El proceso de venta finaliza al ingresar el código -1. c. Eliminar de la estructura los medicamentos con stock en 0. d. Modificar el precio unitario del medicamento de código 30, en $10. Ejercitación Escribir un programa que: a. Lea la información de los clientes y los almacene en una estructura de datos. La lectura finaliza con el nro. de cuenta -1 y los clientes se leen ordenados por nro. de cuenta. Como máximo el banco atiende 10000 clientes. b. Informe el nombre y apellido de los clientes cuyo saldo supera el promedio de los saldos de las cuentas del banco. c. Agregue una nueva cuenta con el nro. siguiente al último nro. de cuenta ingresado para el cliente Juan García en la sucursal La Plata con saldo inicial en $100 en el día de la fecha. d. Informe el nombre y apellido del cliente con nro. de cuenta 4500. e. Informe el nombre y apellido de los clientes con cuentas creadas en el 2000. f. Sabiendo que el nro. de cuenta 3300 no existe, inserte una nueva cuenta con ese nro. para el cliente Ana Paus en la sucursal Ensenada con saldo inicial en$150 en el día de la fecha. g. Elimine un nro. de cuenta determinado. h. Elimine un elemento de una posición determinada. NOTA: Implementar un módulo para cada punto. Número cuenta Sucursal Nombre Apellido Fecha de creación Saldo 2000 Ensenada Juan López 12/02/2000 2000 2100 La Plata Ana Díaz 14/06/1999 2500 3500 City Bell Luis Perez 22/05/2016 3000 4055 Gonnet Pedro Lares 05/12/2010 5500 4500 Gonnet Ema Zanon 06/09/2000 200 6400 La Plata Sofía Lera 05/12/2010 300 7000 Ensenada Raúl Ávila 14/06/1999 800 8250 La Plata Mara García 15/05/2004 500 -1 Un banco requiere el procesamiento de los clientes que posee. De cada cliente se conoce su número de cuenta, sucursal, nombre, apellido, fecha de creación de la cuenta y saldo.
Compartir