Gibt es in C # eine Art SortedListdouble, die eine schnelle Abfrage (mit LINQ) für den nächsten Wert ermöglicht?

8

Ich suche nach einer Struktur, die eine sortierte Menge von Doppelwerten enthält. Ich möchte diese Menge abfragen, um den nächsten Wert für einen angegebenen Referenzwert zu finden.

Ich habe mir das SortedList<double, double> angeschaut, und es ist ziemlich gut für mich. Da ich jedoch keine expliziten Schlüssel / Wert-Paare benötige. das scheint mir zuviel zu sein, und ich frage mich, ob ich es schneller schaffen könnte.

Bedingungen:

  • Die Struktur wird nur einmal initialisiert und ändert sich nie (kein Einfügen / Löschen)
  • Die Anzahl der Werte liegt im Bereich von 100k.
  • Die Struktur wird oft mit neuen Referenzen abgefragt, die schnell ausführen müssen.
  • Aus Gründen der Einfachheit und Geschwindigkeit kann der Wert des Satzes direkt unter der Referenz zurückgegeben werden, nicht der nächstliegende Wert
  • Ich möchte LINQ für die Abfrage verwenden, wenn möglich, um den Code zu vereinfachen.
  • Ich möchte, wenn möglich, keinen 3rd Party Code verwenden. .NET 3.5 ist verfügbar.
  • Die Geschwindigkeit ist wichtiger als der Speicherbedarf

Ich verwende derzeit den folgenden Code, wobei SortedValues das oben erwähnte SortedList

ist %Vor%

Kann ich schneller?

Ich bin auch nicht zu 100% sicher, ob dieser Code wirklich sicher ist. IEnumerable , der Rückgabetyp meiner Abfrage ist per Definition nicht mehr sortiert. Ein Unit-Test mit einer großen Testdatenbank hat aber gezeigt, dass es in der Praxis ist, also funktioniert das für mich. Haben Sie Hinweise zu diesem Aspekt?

P.S. Ich weiß, dass es viele ähnliche Fragen gibt, aber keine beantwortet meine spezifischen Bedürfnisse. Vor allem gibt es diese C # Datenstruktur wie Dictionary aber ohne einen Wert , aber der Fragesteller möchte nur die Existenz überprüfen, nichts finden.

    
Marcel 14.01.2010, 08:07
quelle

3 Antworten

9

Die Art und Weise, wie Sie es tun, ist unglaublich langsam, da es bei jeder O (n) -Performance vom Anfang der Liste aus suchen muss.

Ein besserer Weg besteht darin, die Elemente in eine Liste aufzunehmen und dann die Liste zu sortieren . Sie sagen, dass Sie den Inhalt nicht mehr ändern müssen, wenn er einmal initialisiert wurde. Das einmalige Sortieren reicht aus.

Dann können Sie List<T>.BinarySearch verwenden, um Elemente zu finden oder den Einfügepunkt von zu finden ein Element, wenn es nicht bereits in der Liste vorhanden ist.

Aus der Dokumentation:

  

Rückgabewert

     

Der auf Null basierende Index von   Artikel in der sortierten List<T> ,   wenn ein Gegenstand gefunden wird; andernfalls, a   negative Zahl, die bitweise ist   Ergänzung des Index des nächsten   Element, das größer als Element oder ist,   wenn es kein größeres Element gibt,   bitweises Komplement von Count.

Sobald Sie den Einfügepunkt haben, müssen Sie die Elemente auf jeder Seite überprüfen, um zu sehen, welche am nächsten ist.

    
Mark Byers 14.01.2010, 08:14
quelle
1

Vielleicht ist es Ihnen jetzt nicht nützlich, aber .Net 4 hat eine SortedSet Klasse in der BCL.

    
Winston Smith 14.01.2010 08:44
quelle
-1

Ich denke, es kann eleganter wie folgt sein: Falls Ihre Artikel nicht sortiert sind:

%Vor%

Falls Ihre Artikel sortiert sind, können Sie den OrderBy-Aufruf weglassen ...

    
Amittai Shapira 16.07.2010 09:12
quelle

Tags und Links