Multimnožina

Multimnožina
Multimnožina

Multimnožina (multiset, množina s opakováním, bag) je datový typ vycházející z množiny. Multimnožina slouží jako kontejner na entity, jenž negarantuje pořadí uložených prvků, a který může obsahovat jednotlivé prvky (hodnoty) vícekrát.

Implementace

Nejjednodušším způsobem implementace je použít list a zapomenout na pořadí. Tento způsob je ovšem velmi neefektivní z hlediska použité paměti, pokud se prvky často opakují. Druhou možností je využití dvojice seznamů, z nichž ten první obsahuje hodnoty a druhý zaznamenává počty jejich výskytů. Tento postup je efektivnější, ale stále vyžaduje poměrně náročnou operaci průchodu seznamem pro přístup k jednotlivým položkám (asymptotická složitost O(n)). Z tohoto důvodu se pro efektivní implementaci využívá hashovací tabulka, která umožňuje přístup k položkám s očekávanou konstantní složitostí.

Kód

/**
 * Multimnozina implementovana pomoci dvojice seznamu
 * @author Pavel Micka
 * @param <ENTITY> typovy parametr obsahu
 */
public class Multiset<VALUE> {

    private List<VALUE> values;
    private List<Integer> occurences;

    /**
     * Konstruktor
     * @param initialCapacity kapacita, se kterou je inicializovan podrizeny seznam
     */
    public Multiset(int initialCapacity) {
        values = new ArrayList<VALUE>(initialCapacity);
        occurences = new ArrayList<Integer>(initialCapacity);
    }

    /**
     * Vlozi entitu do multimnoziny
     * @param val dana entita
     * @return pocet vyskytu entity po jejim pridani
     */
    public int put(VALUE val) {
        int index = values.indexOf(val);
        if (index == -1) {
            values.add(val);
            occurences.add(1);
            return 1;
        } else {
            int currCount = occurences.get(index);
            occurences.set(index, currCount + 1);
            return currCount + 1;
        }
    }

    /**
     * Vrati nahodne nejaky prvek z mnoziny (a snizi pocet jeho vyskytu o 1)
     * @return prvek, @null pokud je mnozina prazdna
     */
    public VALUE pick() {
        if (values.size() == 0) {
            return null;
        }
        if (occurences.get(0) == 1) {
            VALUE v = values.remove(0);
            occurences.remove(0);
            return v;
        } else {
            VALUE v = values.get(0);
            occurences.set(0, occurences.get(0) - 1);
            return v;
        }
    }

    /**
     * Odstrani z mnoziny danou entitu (snizi pocet vyskytu o 1)
     * @param val entita
     * @return pocet vyskytu po odstraneni dane entity
     */
    public int remove(VALUE e) {
        int index = values.indexOf(e);
        int curr = occurences.get(index);
        if (curr != 1) {
            occurences.set(index, curr - 1);
            return curr - 1;
        } else {
            values.remove(index);
            occurences.remove(index);
            return 0;
        }
    }

    /**
     *
     * Dotaz na pritomnost dane entity
     * @param val entita
     * @return pocet vyskytu dane entity
     */
    public int contains(VALUE e) {
        int index = values.indexOf(e);
        if(index == -1) return 0;
        return occurences.get(index);
    }

    /**
     * Dotaz na velikost mnoziny (vcetne multiplicit)
     * @return pocet prvku
     */
    public int size() {
        int count = 0;
        for(Integer i : occurences){
            count += i;
        }
        return count;
    }
}
{ zpětná vazba }
Delicious Delicious
Sdílet
Hodnocení (0): 0

Přečtěte si také

Diskuse





Článek zatím nemá žádné komentáře.