unidad didáctica 8

Post on 02-Jul-2022

1 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Tratamientos secuenciales I

Fundamentos de Programación

Departamento de Lenguajes y Sistemas Informáticos

Unidad Didáctica 8

Versión 1.0.0

UD8: Tratamientos secuenciales I

Índice

Introducción

Objetivo

Estructura lógica

Metodología - Resolución de problemas

Tratamientos:

Operaciones aritméticas:

“suma/producto”

Preguntas sobre propiedades:

“existe/para todo”

Máximos, mínimos

UD8: Tratamientos secuenciales I

Introducción

Conceptos necesarios, ya vistos:

Diseño de tipos => creación de objetos.

Diseño de programas iterativos => uso de estructuras de

control iterativas o “bucles” (for clásico, for extendido, while)

Uso de agregados de objetos: List, Set, etc.

Conceptos nuevos:

Extraer información útil para un usuario final sobre los datos

contenidos en un agregado de objetos.

UD8: Tratamientos secuenciales I

Objetivo

Dado un agregado de objetos (un List, un Set, etc.), nos

planteamos preguntas del tipo:

¿cuánto vale la suma de los …?

¿y el producto de los que verifican que …?

¿existe algún objeto que verifique …?

¿todos los objetos que cumplen que … verifican ...?

¿cuál es el valor más grande de los que … ?

¿según el orden … cuál es mayor que … ?

actualiza todos los objetos que …

etc.

Cada una de esas preguntas y otras similares pueden

implementarse a través de métodos con una

ESTRUCTURA COMÚN

UD8: Tratamientos secuenciales I

Estructura lógica – Ejemplo I

¿Cómo se calcula la suma de los cuadrados de los

números enteros contenidos en un Vector de Enteros?

Como el agregado es un Vector usamos un for extendido para

recorrerlo. El código lo concretamos en un método que

tomando un Vector como parámetro devuelve el resultado

esperado.

public static Integer sumaCuadrados(Vector<Integer> v){

}

public static Integer sumaCuadrados(Vector<Integer> v){

Integer suma=0;

for (Integer e: v){

suma = suma + e*e;

}

return suma;

}

UD8: Tratamientos secuenciales I

Estructura lógica – Ejemplo II

Sumar los cuadrados de los enteros contenidos en un

vector o en una secuencia que son múltiplos de 3.

public static Integer sumaCuadradosMultiplos3(Vector<Integer> v){

}

public static Integer sumaCuadradosMultiplos3(Vector<Integer> v){

Integer suma=0;

for(Integer e: v){

if(Enteros.esMultiplo(e,3)){

suma = suma + e*e;

}

}

return suma;

}

public static Integer sumaCuadradosIntervaloMultiplos3(Integer a,

Integer b, Integer c){

}

public static Integer sumaCuadradosIntervaloMultiplos3(Integer a,

Integer b, Integer c){

if(!(b>a && c>0)) throw new IllegalArgumentException();

Integer suma=0;

for(Integer e= a; e<=b; e=e+c){

if(Enteros.esMultiplo(e,3))

suma = suma + e*e;

}

return suma;

}

UD8: Tratamientos secuenciales I

Estructura lógica

¿Cuál es entonces nuestro esquema?

Elementos a destacar:

Acumulador: es una variable que acumula el resultado calculado

hasta ese momento. Se inicializa al valor adecuado para la secuencia o

el agregado vacío y es del tipo del resultado que queramos calcular. En

el ejemplo, la variable es suma que se inicializa a cero y es de tipo

Integer, como el resultado.

Filtro: es una expresión lógica sin efectos laterales que nos sirve para

escoger los elementos del agregado sobre los que vamos a hacer el

cálculo. En este caso es la expresión Enteros.esMultiplo(e,3).

Expresión: es una expresión que a partir de cada objeto del agregado

calcula el valor que se va acumulando. En este caso la expresión es e*e.

UD8: Tratamientos secuenciales I

Metodología - Resolución de problemas

Opciones:

1. Resolución mediante construcción directa de un bucle

(for extendido).

2. Generalización del código: diseño con tipos genéricos

e identificando las partes variables del método. Éstas se

pasarán como parámetros. En el caso de que el agregado

sea un Vector, las partes variables son: el agregado, el

filtro y la expresión.

A CONTINUACIÓN …

CLASE COLECCIONES(segunda parte de la asignatura)

UD8: Tratamientos secuenciales I

Operaciones aritméticas

Sumatorio

• Operador: +

• Elemento Neutro: 0

ESQUEMA:

Double suma = 0.0;

for(T o: it){

if(…){

suma = suma + … ;

}

}

return suma;

UD8: Tratamientos secuenciales I

Operaciones aritméticas

public static Integer suma(List<Integer> l){

Integer suma = 0;

for(Integer e: l)

suma = suma + e;

return suma;

}

99 44 33 11 22

Iteración nº e suma

77

0 … 0

UD8: Tratamientos secuenciales I

Operaciones aritméticas

public static Integer suma (List<Integer> l){

Integer suma = 0;

//mostrar(“suma”+suma);

for(Integer e: l){

suma = suma + e;

//mostrar(e);

//mostrar(“suma”+suma);

}

return suma;

}

99 44 33 11 22

Iteración nº e suma

77

0 … 0

1 7 (0+7)

2 9 (0+7)+9

3 4 ((0+7)+9)+4 … etc …

UD8: Tratamientos secuenciales I

Operaciones aritméticas

Producto

• Operador: *

• Elemento Neutro: 1

ESQUEMA:

Double prod = 1.0;

for(T o: it){

if(…){

prod = prod * … ;

}

}

return prod;

UD8: Tratamientos secuenciales I

Preguntas sobre propiedades

P Q ! P P || Q P && Q

true true false true true

true false false true false

false true true true false

false false true false false

(Repasemos cómo funcionan los operadores lógicos)

TABLA DE VERDAD:

UD8: Tratamientos secuenciales I

Preguntas sobre propiedades

Propiedad:

¿para todo elemento se verifica?

• Operador: &&

• Elemento Neutro: true

ESQUEMA:

Boolean r = true;

for(T o: it){

if(…){

r = r && … ;

}

}

return r;

UD8: Tratamientos secuenciales I

Preguntas sobre propiedades

Propiedad:

¿existe algún elemento que verifica que …?

• Operador: ||

• Elemento Neutro: false

ESQUEMA:

Boolean r = false;

for(T o: it){

if(…){

r = r || … ;

}

}

return r;

UD8: Tratamientos secuenciales I

Preguntas sobre propiedades

// ¿Existe algún número par en v?

public static Boolean existePar (List<Integer>

l){

Boolean res = false;

for(Integer e: l)

res = res || (e%2==0);

return res;

}

99 44 33 11 22

Iteración nº ¿e es par? res

77

UD8: Tratamientos secuenciales I

Preguntas sobre propiedades

// ¿Existe algún número par en v?

public static Boolean existePar (List<Integer> l){

Boolean res = false;

for(Integer e: l)

res = res || (e%2==0);

return res;

}

99 44 33 11 22

Iteración nº ¿e es par? res

0 --- false

1 false false || false -> false

2 false false || false -> false

3 true false || true -> true

4

77

false true || false -> true … etc …

¿Cómo sería un método que responda si todos los elementos son números pares?

UD8: Tratamientos secuenciales I

Preguntas sobre propiedades

// ¿Existe algún número par en v?

public static Boolean existePar (List<Integer> l){

Boolean res = false;

for(Integer e: l)

res = res || (e%2==0);

return res;

}

Nota:

Tratamiento no eficiente pues encuentra un

elemento que cumple la propiedad y sin

embargo sigue con las comprobaciones.

¿cómo podemos conseguir la eficiencia?

UD8: Tratamientos secuenciales I

Preguntas sobre propiedades//Versión eficiente nº1: (uso de break)

public static Boolean existeParEficienteN1 (List<Integer> l){

Boolean res = false;

for(Integer e: l){

res = res || (e%2==0);

if(e%2==0)

break;

}

}

return res;}

//Versión eficiente nº2: (“variable de frenado” dentro de un while)

public static Boolean existeParEficienteN2 (List<Integer> l){

Boolean res = false;

int i=0;

while(i<l.size() && !res){

if(l.get(i)%2==0){

res = true;

}

i++;//¿qué ocurre si olvidamos esta instrucción?

}return res;}

UD8: Tratamientos secuenciales I

Preguntas sobre propiedades

¿para todo …? VERSIÓN EFICIENTE

ESQUEMA:

Boolean r = true;

for(T o: it){

if(…){

r = r && … ;

if(!r){

break;

}

}

}

return r;

UD8: Tratamientos secuenciales I

Preguntas sobre propiedades

¿existe …? VERSIÓN EFICIENTE

ESQUEMA:

Boolean r = false;

for(T o: it){

if(…){

r = r || … ;

if(r){

break;

}

}

}

return r;

UD8: Tratamientos secuenciales I

Máximos, mínimos

máximo vs. mínimo:

• Elemento neutro: null

• Operador:

operación comparación 2 a 2

ESQUEMA:T a=null;

for(T e:it)

//a = (a==null? e: Utiles.max(e,a));

if(a==null)

a = e;

else

a = Utiles.max(e,a);

return a;

(análogo para

el mínimo)

UD8: Tratamientos secuenciales I

Máximos, mínimos

máximo vs. mínimo: (versión con filtrado)

• Elemento neutro: null

• Operador:

operación comparación 2 a 2

ESQUEMA:T a=null;

for(T e:it)

if(…){

a = (a==null? e: Utiles.max(e,a));

}

if(a==null)

throw new NoSuchElementException(“…”);

return a;

(análogo para

el mínimo)

UD8: Tratamientos secuenciales I

Máximos, mínimos

99 44 33 11 22

Iteración nº ¿mayor(a,res)->? resultado

77

0

1

2

3

4

resultado ->7 ---

(7,9)->9 resultado ->9

(9,4)->9 resultado ->9

… etc …

UD8: Tratamientos secuenciales I

Máximos, mínimos

//El ejemplo anterior:(versión “intuitiva”)

public static Integer maxValor(List<Integer> l){

//Primer candidato el primer elemento

Integer res = l.get(0);

for(Integer e:l){//¿Nuevo elemento mayor? Si fuera así, lo cambio

if(res.compareTo(e)<0)//if(res<e)

res = e;

}

return res ;

}

UD8: Tratamientos secuenciales I

Máximos, mínimos

/*El ejemplo anterior:

*(versión basada en operador binario máximo de dos

*elementos)*/

public static Integer

maxValor_version2(List<Integer> l){

Integer a=null;

for(Integer e:l)

a = a==null? e: Utiles.max(e,a);

return a;

}

UD8: Tratamientos secuenciales I

Máximos, mínimos

public class Utiles{

/*Método auxiliar para calcular el máximo de dos

*elementos: tipos genéricos (ampliando a

*supertipos) usando orden natural del tipo */

public static <E extends Comparable<? super

E>> E max(E e1, E e2){

return e1.compareTo(e2)>= 0 ? e1 : e2;

}

// …

}

UD8: Tratamientos secuenciales I

Máximos, mínimos

El esquema para el máximo y el mínimo puede ser

mejorado si el tratamiento del primer elemento es

incluido en el máximo binario:

//Versión “robusta” de max binario

public static <T extends Comparable<? super T>> T max(T o1, T o2) {

T o=null;

if(o1!=null && o2!=null){

if(o1.compareTo(o2)>=0)

o=o1;

else

o=o2;

} else {

if(o1==null)

o=o2;

if(o2==null)

o=o1;

}

return o;

}

UD8: Tratamientos secuenciales I

Máximos, mínimos

máximo vs. mínimo: versión mejorada

El tratamiento del primer elemento está incluido en el

operador binario Utiles.max(-,-).

ESQUEMA:T a=null;

for(T e:it)

a = Utiles.max(e,a);

}

return a;

Nota 1: la opción de filtrado se puede añadir de

manera análoga a como se hizo con la versión anterior

Nota 2: el uso del operador Utiles.max(-,-) en su

versión robusta evita el disparo de excepciones

cuando haya valores perdidos (null) en el agregado.

(análogo para

el mínimo)

UD8: Tratamientos secuenciales I

Búsquedas

Búsqueda

• Operador: =

• Elemento Neutro: --

ESQUEMA:

T b = null;

for(T e: it){

if(...){

b=e;

break;

}

}

return b;

top related