POO-ITBA / 2024_01

Consultas 1C 2024
0 stars 0 forks source link

Ejercicio 8 y 9 Guia 6 #12

Open BrunTac opened 5 months ago

BrunTac commented 5 months ago

Buenas! Tenia consultas sobre dos de los últimos ejercicios de la guía 6.

En el 8, la implementacion en las soluciones usa un mapa, pero yo use una lista. Elegir una lista en este caso seria incorrecto aunque me de bien el código de prueba? Adjunto abajo el código.

public class BagImpl<T> implements Bag<T> {

    private List<T> bag = new ArrayList<>();

    public boolean add(T o) {
        return bag.add(o);
    }

    public int size() {
        return bag.size();
    }

    public boolean contains(T o) {
        return bag.contains(o);
    }

    public int count(T o) {
        int count = 0;
        for(T thing : bag)
            if(o.equals(thing))
                count++;
        return count;
    }

    public int sizeDistinct() {
        int count = 0;
        List<T> seen = new ArrayList<>();
        for(T thing : bag)
            if(!seen.contains(thing)) {
                seen.add(thing);
                count++;
            }
        return count;
    }

    public void remove(T o) {
        if(!bag.remove(o))
            throw new NoSuchElementException();
    }

} 

En el 9 la consulta es prácticamente la misma pero medio al revés. Yo implemente TimeSet usando un mapa en vez del set usado en las soluciones. Misma pregunta que el anterior. Adjunto abajo el código.

public class TimePair implements Comparable<TimePair>{

    private int hours;
    private int minutes;

    public TimePair(int hours, int minutes) {
        this.hours = hours;
        this.minutes = minutes;
    }

    public TimePair() {}

    public int getHours() {
        return hours;
    }

    public int getMinutes() {
        return minutes;
    }

    public void setTime(int hours, int minutes) {
        this.hours = hours;
        this.minutes = minutes;
    }

    public void setMinutes(int minutes) {
        this.minutes = minutes;
    }

    public int compareTo(TimePair t) {
        int toReturn = hours - t.getHours();
        if(toReturn == 0)
            toReturn = minutes - t.getMinutes();
        return toReturn;
    }

public class TimeSetImpl<T> implements TimeSet<T> {

    private Map<T, TimePair> timeSet = new HashMap<>();

    public void add(T elem, int hours, int minutes) {
        if(hours < 0 || hours > 23 || minutes < 0 || minutes > 59)
            throw new IllegalArgumentException();
        timeSet.putIfAbsent(elem, new TimePair());
        timeSet.get(elem).setTime(hours, minutes);
    }

    public void remove(T elem) {
        timeSet.remove(elem);
    }

    public int size() {
        return timeSet.size();
    }

    public boolean contains(T elem) {
        return timeSet.containsKey(elem);
    }

    public Set<T> retrieve(int hoursFrom, int minutesFrom, int hoursTo, int minutesTo) {
        TimePair tFrom = new TimePair(hoursFrom, minutesFrom);
        TimePair tTo = new TimePair(hoursTo, minutesTo);
        if(hoursFrom < 0 || hoursFrom > 23 || minutesFrom < 0 || minutesFrom > 59
                || hoursTo < 0 || hoursTo > 23 || minutesTo < 0 || minutesTo > 59
                || tFrom.compareTo(tTo) > 0)
            throw new IllegalArgumentException();
        Set<T> toReturn = new HashSet<>();
        for(T elem : timeSet.keySet())
            if(timeSet.get(elem).compareTo(tFrom) >= 0 && timeSet.get(elem).compareTo(tTo) <= 0)
                toReturn.add(elem);
        return toReturn;
    }

Gracias de antemano!

fmeola commented 5 months ago

Hola @BrunTac

Ejercicio 8 La implementación es incorrecta porque estás repitiendo información. Ya en el ejercicio del bag en Programación Imperativa no estaba bien guardar varias veces el mismo elemento sino que lo guardábamos una sola vez asociándolo a una cantidad de apariciones. Acá hacemos lo mismo pero ahora utilizando un mapa donde la clave es el objeto y el valor es la cantidad de apariciones de ese objeto.

Ejercicio 9 En vez de tener una sola colección donde cada elemento tiene el T y el TimePair vos tenés un mapa donde asociás un T con un TimePair. Usando keySet, values o entrySet podés elegir si querés recorrer los T, los TimePair o ambos. El tema está en el método retrieve. Como es un HashMap cuando vos iterás por las claves estas no tienen orden entonces no podés hacer la optimización de que retrieve no siempre tenga que recorrer la colección hasta el final. Sacando esa optimización, lo demás está bien. Además en el retrieve hacés:

        for(T elem : timeSet.keySet())
            if(timeSet.get(elem).compareTo(tFrom) >= 0 && timeSet.get(elem).compareTo(tTo) <= 0)
                toReturn.add(elem);

Como es un mapa estás iterando por keySet y luego hacés un get. Mejor iterar por entrySet y usar entry.getValue().

BrunTac commented 5 months ago

Perfecto, todo entendido. Muchas gracias!