Qual è la complessità computazionale del metodo Groovy unique ()?

3

Domanda 1

Qual è la complessità computazionale del metodo Groovy unique() ?

Domanda 2

Come ho potuto capire da solo? Il metodo unique() è definito nella classe DefaultGroovyMethods . Il codice sorgente può essere trovato qui: org. codehaus.groovy.runtime.DefaultGroovyMethods . Puoi indicarmi il pezzo di codice che illustra la risposta alla domanda 1?

    
posta Lernkurve 20.06.2013 - 10:29
fonte

1 risposta

6

Poiché Lernkurve ha evidenziato nei commenti, l'implementazione fornita nel codice sorgente di Groovy sembra essere O (n ^ 2) .

public static <T> Collection<T> unique(Collection<T> self, boolean mutate) {
    List<T> answer = new ArrayList<T>();
    for (T t : self) {                    // << Outer loop over each item
        boolean duplicated = false;
        for (T t2 : answer) {             // << Inner loop over each found item
            if (coercedEquals(t, t2)) {
                duplicated = true;
                break;
            }
        }
        if (!duplicated)
            answer.add(t);
    }
    if (mutate) {
        self.clear();
        self.addAll(answer);
    }
    return mutate ? self : answer ;
}

Il ciclo esterno assicura che la complessità temporale sia almeno pari a O (n), poiché crescerà in modo lineare man mano che l'elenco di input cresce. Allo stesso modo, il ciclo interno preso da solo è O (n). Per ogni elemento nell'elenco di input, quindi scorre su ogni elemento che è registrato nell'elenco "risposta" per vedere se quell'elemento è già contenuto. Mettili insieme e hai una funzione O (n ^ 2).

Come ho sottolineato nei commenti, ci sono alcuni modi per ottenere prestazioni migliori da questo, per grandi serie. Se sei disposto a spendere un po 'di memoria in più, puoi usare un set di hash di qualche tipo per registrare se un elemento è già stato incluso o meno. Questi hanno generalmente un tempo di ricerca O (1) per verificare se l'elemento corrente è univoco nell'elenco.

In alternativa, l'ordinamento dell'elenco di input (se è ordinabile) con una buona funzione di ordinamento (la maggior parte di quelli inclusi nella libreria standard di una lingua sarà O (n log n)) può aiutare, presumendo che non ti interessi ordine dell'elenco di output "univoco". In questo modo puoi essere sicuro che gli elementi duplicati appariranno sempre in sequenza tra loro e diventa banale rifiutarli dall'output.

    
risposta data 20.06.2013 - 16:10
fonte

Leggi altre domande sui tag