Was ist bei zwei Listen (nicht unbedingt sortiert) der effizienteste nicht rekursive Algorithmus, um den Schnittpunkt dieser Listen zu finden?
algorithm
list
set-intersection
mwfearnley
quelle
quelle
Antworten:
Sie können alle Elemente der ersten Liste in ein Hash-Set einfügen. Wiederholen Sie dann das zweite und überprüfen Sie für jedes seiner Elemente den Hash, um festzustellen, ob er in der ersten Liste vorhanden ist. Wenn ja, geben Sie es als Element der Kreuzung aus.
quelle
Vielleicht möchten Sie einen Blick auf Bloom-Filter werfen. Sie sind Bitvektoren, die eine probabilistische Antwort geben, ob ein Element Mitglied einer Menge ist. Die eingestellte Schnittmenge kann mit einer einfachen bitweisen UND-Verknüpfung implementiert werden. Wenn Sie eine große Anzahl von Null-Schnittpunkten haben, können Sie diese mithilfe des Bloom-Filters schnell entfernen. Sie müssen jedoch immer noch auf einen der anderen hier genannten Algorithmen zurückgreifen, um den tatsächlichen Schnittpunkt zu berechnen. http://en.wikipedia.org/wiki/Bloom_filter
quelle
Ohne Hashing haben Sie vermutlich zwei Möglichkeiten:
quelle
O(n + m)
aber nicht immer möglich.O(n lg n) * 2 + O(n) * 2
die gleich ist wieO(n lg n)
.Aus der Liste der eviews-Funktionen geht hervor, dass komplexe Zusammenführungen und Verknüpfungen unterstützt werden (wenn dies wie in der DB-Terminologie "Verknüpfung" ist, wird eine Schnittmenge berechnet). Stöbern Sie jetzt in Ihrer Dokumentation :-)
Zusätzlich hat eviews ein eigenes Benutzerforum - warum nicht dort fragen?
quelle
Erstellen Sie mit Satz 1 einen binären Suchbaum mit
O(log n)
und iterieren Sie Satz 2 und suchen Sie dieBST m X O(log n)
GesamtsummeO(log n) + O(m)+O(log n) ==> O(log n)(m+1)
quelle
In C ++ kann Folgendes mithilfe der STL-Map versucht werden
quelle
Hier ist eine weitere mögliche Lösung, die ich mir ausgedacht habe, um O (nlogn) in zeitlicher Komplexität und ohne zusätzlichen Speicherplatz zu verwenden. Sie können es hier überprüfen https://gist.github.com/4455373
So funktioniert es: Angenommen, die Sätze enthalten keine Wiederholungen, führen Sie alle Sätze zu einem zusammen und sortieren Sie sie. Durchlaufen Sie dann die zusammengeführte Menge und erstellen Sie bei jeder Iteration eine Teilmenge zwischen dem aktuellen Index i und i + n, wobei n die Anzahl der im Universum verfügbaren Mengen ist. Was wir beim Schleifen suchen, ist eine sich wiederholende Folge der Größe n, die der Anzahl der Mengen im Universum entspricht.
Wenn diese Teilmenge bei i gleich dieser Teilmenge bei n ist, bedeutet dies, dass das Element bei i n-mal wiederholt wird, was der Gesamtzahl der Mengen entspricht. Und da es in keiner Menge Wiederholungen gibt, bedeutet dies, dass jede der Mengen diesen Wert enthält, also fügen wir ihn dem Schnittpunkt hinzu. Dann verschieben wir den Index um i +, was zwischen ihm und n verbleibt, da definitiv keiner dieser Indizes eine sich wiederholende Sequenz bilden wird.
quelle
Sortieren Sie zunächst beide Listen mit Quicksort: O (n * log (n). Vergleichen Sie dann die Listen, indem Sie zuerst die niedrigsten Werte durchsuchen und die allgemeinen Werte hinzufügen. Beispiel: in lua):
Welches ist
O(max(n, m))
won
undm
sind die Größen der Listen.BEARBEITEN: Quicksort ist rekursiv, wie in den Kommentaren erwähnt, aber es sieht so aus, als gäbe es nicht rekursive Implementierungen
quelle
Die Verwendung von Sprungzeigern und SSE-Anweisungen kann die Effizienz von Listenkreuzungen verbessern.
quelle
Warum implementieren Sie nicht Ihre eigene einfache Hash-Tabelle oder Hash-Set? Es lohnt sich, keine Überschneidungen zu vermeiden, wenn Ihre Listen groß sind, wie Sie sagen.
Da Sie vorher ein wenig über Ihre Daten wissen, sollten Sie in der Lage sein, eine gute Hash-Funktion auszuwählen.
quelle
Ich stimme der Idee der "Sets" zu. In JavaScript können Sie die erste Liste verwenden, um ein Objekt zu füllen, wobei Sie die Listenelemente als Namen verwenden. Anschließend verwenden Sie die Listenelemente aus der zweiten Liste und prüfen, ob diese Eigenschaften vorhanden sind.
quelle
Wenn Sets (wie Sie sie im Titel nennen) als integriert unterstützt werden, gibt es normalerweise eine Schnittmethode.
Wie auch immer, wie jemand sagte, Sie könnten es leicht machen (ich werde keine Postleitzahl posten, jemand hat es bereits getan), wenn Sie die Listen sortiert haben. Wenn Sie keine Rekursion verwenden können, gibt es kein Problem. Es gibt schnell rekursionsfreie Implementierungen.
quelle
Ich habe ein paar gute Antworten aus diesen , dass Sie in der Lage sein können , anzuwenden. Ich habe noch keine Gelegenheit, sie auszuprobieren, aber da sie auch Kreuzungen abdecken, können Sie sie nützlich finden.
quelle
In PHP so etwas wie
quelle
Aus der Definition der Big-Oh-Notation:
Was in der Praxis bedeutet, dass, wenn die beiden Listen relativ klein sind, weniger als 100 Elemente in jeweils zwei for-Schleifen gut funktionieren. Durchlaufen Sie die erste Liste und suchen Sie in der zweiten nach einem ähnlichen Objekt. In meinem Fall funktioniert es einwandfrei, da ich nicht mehr als 10 - 20 maximale Elemente in meinen Listen habe. Eine gute Lösung ist jedoch, das erste O (n log n) zu sortieren, das zweite auch O (n log n) zu sortieren und sie zusammenzuführen Die beiden Listen sind gleich groß.
quelle