2010-06-12 4 views
13

A Google CollectionsMultiset es un conjunto de elementos cada uno de los cuales tiene un recuento (es decir, puede estar presente varias veces).Encuentra los principales N elementos en un Multiset de Google Collections?

No puedo decirle cuántas veces yo quiero hacer la siguiente

  1. Hacer un histograma (exactamente Multiset)
  2. Obtener los mejores N elementos de recuento de histograma

Ejemplos: 10 mejores URL (por # veces mencionadas), 10 etiquetas principales (por # veces aplicadas), ...

¿Cuál es la forma canónica de hacer # 2 dado un Google Collections Multiset?

Here es una publicación de blog al respecto, pero ese código no es exactamente lo que quiero. Primero, devuelve todo, no solo la parte superior N. En segundo lugar, copia (¿es posible evitar una copia?). En tercer lugar, generalmente quiero un tipo determinista, es decir, tiebreak si los recuentos son iguales. Otros liendres: no es estática, etc.

Respuesta

4

escribí métodos con el la funcionalidad básica que está solicitando, excepto que realizan copias y carecen de una lógica determinista de desempate. Actualmente son internos de Google, pero podemos abrirlos en algún momento. Esta Guava issue tiene las firmas de método.

Su algoritmo es similar a la publicación del blog: ordenando una lista de entradas. Sería más rápido, pero más complicado, usar un mejor selection algorithm.

EDIT: desde el 11 de guayaba, esto es implemented

+0

cómo usarlo para obtener los N elementos superiores? –

3

Para dar otro punto de vista para que la gente comenta en, voy a publicar una versión ligeramente modificada de la entrada del blog hice referencia:

package com.blueshiftlab.twitterstream.summarytools; 

import com.google.common.collect.ImmutableList; 
import com.google.common.collect.Multiset; 
import com.google.common.collect.Ordering; 
import com.google.common.collect.Multiset.Entry; 

public class Multisets { 
    // Don't construct one 
    private Multisets() { 
    } 

    public static <T> ImmutableList<Entry<T>> sortedByCount(Multiset<T> multiset) { 
     Ordering<Multiset.Entry<T>> countComp = new Ordering<Multiset.Entry<T>>() { 
      public int compare(Multiset.Entry<T> e1, Multiset.Entry<T> e2) { 
       return e2.getCount() - e1.getCount(); 
      } 
     }; 
     return countComp.immutableSortedCopy(multiset.entrySet()); 
    } 

    public static <T> ImmutableList<Entry<T>> topByCount(Multiset<T> multiset, 
      int max) { 
     ImmutableList<Entry<T>> sortedByCount = sortedByCount(multiset); 
     if (sortedByCount.size() > max) { 
      sortedByCount = sortedByCount.subList(0, max); 
     } 

     return sortedByCount; 
    } 
} 
+0

Si he entendido bien, esta solución a copiar y ordenar toda la colección cada vez que se desea recuperar los elementos principales N. No estoy seguro de cuáles son sus requisitos, pero la solución Heap-sort-ish lo supera tanto en tiempo como en espacio, así que no estoy seguro de cuál es el beneficio. – danben

+0

Estás optimizando la velocidad, estoy buscando el menor número de líneas de código escritas por mí. – dfrankow

+0

Veo, eso no quedó claro en su publicación, especialmente porque usted pidió evitar hacer una copia. – danben

Cuestiones relacionadas