Wählen Sie Element mit Max Vorkommen in Multiset

8

Ich möchte die Frage zu "Wie wähle ich das erste Element in einem Multiset?" weil es scheint, Multiset ist bereits nach Frequenzen geordnet.

Ich habe ein Multiset myList = Multiset.create ();

%Vor%

Ich konnte keine Methode wie myList.getIndex (0) finden. Bitte beachten Sie, dass ich am Ende die Anzahl der Elemente mit der maximalen Häufigkeit benötige.

Gibt es dafür einen Liner? Oder muss ich diese Iteration machen?

Aktualisierung: Ich bekomme maximale Häufigkeit mit:

%Vor%

Aber das ist zu langsam. Kannst du mir bitte vorschlagen, was genau ich verwenden soll?

Update 1: Die Verwendung der obigen copyHighestCountFirst-Methode erweist sich als zu langsam. In einer Instanz der Schleife dauert es 80 + Millisekunden im Gegensatz zu den durchschnittlichen 40 Millisekunden, ohne sie zu verwenden. In großen Schleifen, sollte ich einfache Iteration bevorzugen?

Update 2: Es funktioniert mit:

%Vor%

Ohne fast null Auswirkungen auf die Leistung. Ich frage mich immer noch, ob es einen besseren Weg gibt, es zu tun.

Nebenbemerkung: In Python habe ich das Gleiche gemacht mit:

%Vor%     
akshayb 23.05.2013, 14:00
quelle

4 Antworten

14

Es gab viele Alternativen zwischen Ihrer Frage und der anderen Antwort, aber viele von ihnen scheinen von der Idee zu abhängig zu sein, dass .get(0) oder .iterator().next() Ihnen am häufigsten helfen wird. Es wird nicht!

Ihre zwei einzigen anständigen Optionen sind Multisets.copyHighestCountFirst(bag).elementSet().iterator().next() , was verschwenderisch ist, wie Sie sagen, oder die entrySet manuell durchlaufen und jedes überprüfen, um zu sehen, ob es bisher am häufigsten ist.

Sie sollten eine Guava-Feature-Anfrage einreichen, um das häufigste Element zu extrahieren. Ich kann nicht versprechen, was daraus wird, aber es lohnt sich, danach zu fragen.

    
Kevin Bourrillion 24.05.2013, 19:27
quelle
3

Eine alternative Lösung, die keine explizite Schleife benötigt - aber in linearer Zeit in der Anzahl der verschiedenen Elemente läuft, was die meisten dieser anderen Lösungen nicht können - wäre

%Vor%     
Louis Wasserman 24.05.2013 23:44
quelle
2

Wegen Ihrer Bearbeitungen und Formulierungen ist nicht klar, was Sie wollen. Auch die Verwendung von myList als Variablenname, was ein Multiset ist, ist nicht beschreibend - ich werde bag als Variablennamen für Multiset verwenden (es ist immerhin Tasche).

  1. " es scheint, Multiset ist bereits nach Frequenzen geordnet " - ist es oder ist es nicht nach Frequenzen geordnet?

    %Vor%

    ist [c0ffee x 2, abba, mfl x 3] , weil die Reihenfolge der Anzeigen verwendet wird, sodass Ihre Sammlung durch Zufall zufällig geordnet werden kann (ich weiß nicht, ob es sich hier um einen Fall handelt). Wenn Sie sich bei der Bestellung nicht sicher sind, verwenden Sie einfach

    %Vor%

    was [mfl x 3, c0ffee x 2, abba] ergibt. Da Multisets.copyHighestCountFirst unveränderbares Multiset zurückgibt, müssen Sie es nicht in der Schleife verwenden, wenn sich Ihr Multiset nicht ändert. Wenn Sie nur einen dummen Mikrobenchmark gemacht haben und gesehen haben, dass die Verwendung von Multisets.copyHighestCountFirst doppelt so langsam ist, was 80 ms vs 40 ms bedeutet - vergessen Sie es, weil vorzeitige Optimierung ist die Wurzel allen Übels . Ich nehme an, wir haben zu diesem Zeitpunkt sortedBag richtig bestellt.

  2. Von dem, was ich sehe, wollen Sie das häufigste Element in bag zählen, was einfach ist:

    %Vor%

    oder wenn Ihr Multiset ImmutableMultiset :

    ist %Vor%

    Beachten Sie, dass sortedBag.entrySet() eine Sammlung von Multiset.Entry , die sowohl Element als auch Zählung hat, wählen Sie also eine, die Sie wollen.

  3. ImmutableMultiset ermöglicht es Ihnen, die ImmutableList -Ansicht zu verwenden, auf der Sie get(0) aufrufen können, um das Element abzurufen:

    %Vor%

    gibt Ihnen nur ein Element (hier: eine Zeichenkette) ohne Anzahl, wenn Sie also nur ein Element holen wollen, können Sie asList() verwenden anstatt mit Iterator zu spielen.

Xaerxess 23.05.2013 15:23
quelle
1

Ich hatte heute eine ähnliche Herausforderung, als ich versuchte, eine einfache, einigermaßen effiziente Methode zu finden, das Element in Multiset mit der maximalen Anzahl zu finden. In der Zukunft, in der wir mit Java 8 leben, konnte ich Louis Wassermans Lösung in einen sauberen Einliner verwandeln:

multiset.entrySet().stream().max(Ordering.natural().onResultOf(Multiset.Entry::getCount)).get();

Dies gibt Ihnen die Multiset.Entry mit der maximalen Anzahl (vorausgesetzt, multiset ist nicht leer), sodass Sie entweder auf das Element oder seine Anzahl zugreifen können.

    
Spencer Kelley 04.04.2018 21:30
quelle

Tags und Links