Überlappungen zwischen zwei Bereichen ohne Sets abziehen

8

KEINE SETS!

Ich kann keine Sets verwenden, weil:

  • Die Bereiche werden zu lang sein.
  • Sie werden zu viel Speicher verbrauchen
  • Die Erstellung der Sets selbst wird zu lange dauern.

Gibt es nur die Endpunkte der Bereiche, um zwei Listen von Bereichen optimal zu subtrahieren?

Beispiel:

%Vor%

Weitere Informationen:

  • r2 muss sich nicht mit r1
  • überschneiden
  • r1 und r2 haben keine Paare, die andere Paare überlappen. Zum Beispiel wird r1 nicht sowohl (0,30) als auch (10, 25)
  • haben

Danke.

    
sequenceGeek 24.06.2011, 01:02
quelle

7 Antworten

11

Das Intervall -Paket enthält möglicherweise alles, was Sie benötigen.

%Vor%     
Ned Deily 24.06.2011, 02:35
quelle
4

Eine Lösung (zusätzlich zu all den anderen verschiedenen Lösungen, die hier vorgestellt wurden) ist die Verwendung eines Intervall- / Segmentbaums (sie sind wirklich das Gleiche):

Ссылка

Ссылка

Ein großer Vorteil dabei ist, dass es einfach ist, beliebige boolesche Operationen (nicht nur Subtraktionen) mit demselben Code auszuführen. Diese Datenstruktur wird standardmäßig in de Berg behandelt. Um eine boolesche Operation für ein Paar von Intervallbäumen durchzuführen (einschließlich der Subtraktion), fügen Sie sie einfach zusammen. Hier ist ein (zugegebenermaßen naive) Python-Code dafür, dies mit unsymmetrischen Bereichsbäumen zu tun. Die Tatsache, dass sie unausgewogen sind, hat keinen Einfluss auf die Zeit, die zum Zusammenführen der Bäume benötigt wird, jedoch ist die Baumkonstruktion hier der wirklich dumme Teil, der letztendlich quadratisch ist (außer die Reduzierung wird durch Partitionierung ausgeführt, was ich irgendwie bezweifle). Wie auch immer du gehst:

%Vor%

Ich schrieb diese Art von schnell und habe es nicht so viel getestet, so dass es Fehler geben konnte. Beachten Sie auch, dass dieser Code mit beliebigen booleschen Operationen arbeitet, nicht nur mit Unterschieden (Sie übergeben sie einfach als Argument an op in der Zusammenführung). Die zeitliche Komplexität der Auswertung von diesen ist linear von der Größe des Ausgabebaums (was auch die gleiche ist wie die Anzahl der Intervalle im Ergebnis). Als Beispiel habe ich den Fall ausgeführt, den Sie angegeben haben:

%Vor%

Und ich habe folgende Ausgabe:

  

[(1, 29), (51, 59), (201, 1000), (1100, 1149)]

Das scheint mit dem übereinzustimmen, was Sie erwarten würden. Wenn Sie nun andere boolesche Operationen ausführen möchten, ist dies die gleiche Funktion:

%Vor%     
Mikola 24.06.2011 02:32
quelle
1

Hier ist eine schnelle Python-Funktion, die die Subtraktion durchführt, unabhängig davon, ob die Anfangslisten wohlgeformt sind (d. h. die Listen vor der Subtraktion in die kleinste Liste äquivalenter Bereiche sortiert, sortiert):

%Vor%     
Aaron Dufour 24.06.2011 02:36
quelle
1

Ich glaube, ich habe die Frage falsch verstanden, aber dieser Code funktioniert, wenn r2 eine Untermenge von r1

ist %Vor%

dann tust du:

Aktualisieren : Beachten Sie, dass das letzte Intervall von r2 anders ist, als es zu funktionieren.

%Vor%     
JBernardo 24.06.2011 02:11
quelle
1

Spaßfrage! Eine andere Implementierung, obwohl Sie bereits viel haben. Es war interessant zu tun! Umfasst einige zusätzliche "Dekoration", um das, was ich mache, deutlicher zu machen.

%Vor%

Ich bekomme die richtige Ausgabe:

%Vor%     
weronika 24.06.2011 05:26
quelle
1

Das war ein interessantes Problem!

Ich denke, das ist richtig, und es ist ziemlich kompakt. Es sollte mit überlappenden Bereichen aller Arten arbeiten, aber es nimmt wohlgeformte Bereiche an (d. H.% Co_de% wo [x, y) ). Es verwendet x < y style-Bereiche zur Vereinfachung. Es basiert auf der Beobachtung, dass es wirklich nur sechs mögliche Anordnungen gibt (mit Ergebnissen in ()):

Bearbeiten : Ich habe eine kompaktere Darstellung gefunden:

%Vor%

Bei einer sortierten Liste von Endpunkten, wenn [x, y) , sollten die ersten beiden Endpunkte im Ergebnis enthalten sein. Wenn endpoints[0] == s1 , dann sollten die letzten beiden Endpunkte im Ergebnis sein. Wenn keine, dann sollte es kein Ergebnis geben.

Ich habe es nicht viel getestet, daher ist es durchaus möglich, dass etwas nicht stimmt. Bitte lassen Sie mich wissen, wenn Sie einen Fehler finden!

%Vor%

Getestet:

%Vor%     
senderle 24.06.2011 03:31
quelle
0

Das ist ziemlich hässlich, aber es funktioniert für das gegebene Beispiel

%Vor%

druckt:

%Vor%     
Dan D. 24.06.2011 02:11
quelle

Tags und Links