vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
Blitzschnelles Erstellen von grafischen Diagrammen!  
 vb@rchiv Quick-Search: Suche startenErweiterte Suche starten   RSS-Feeds  | Newsletter  | Impressum  | Datenschutz  | vb@rchiv CD Vol.6  | Shop Copyright ©2000-2018
 
zurück
Rubrik: Verschiedenes / Sonstiges   |   VB-Versionen: VB2005, VB200812.02.09
DoubleComparer

Ein Comparer für Array.Copy, der Double.Nan-Werte korrekt sortiert

Autor:   Manfred BohnBewertung:     [ Jetzt bewerten ]Views:  7.074 
ohne HomepageSystem:  Win2k, WinXP, Vista, Win7, Win8, Win10kein Beispielprojekt 

Beim Sortieren der Daten in einem eindimensionalen Double-Array durch die Methode 'Array.Copy' tritt bei Verwendung des Standard-Comparers bekanntlich das Problem auf, dass Double.Nan-Werte nicht an den Anfang oder das Ende des Array gerückt werden, sondern nach dem Sortieren 'irgendwo' zwischen den Daten stehen. (Das liegt vermutlich daran, dass die Prüfung, ob ein Double-Wert 'Nan' enthält, sehr rechenzeitaufwendig.)

Allerdings: Der Sortiervorgang kann bei Verwendung des Standard-Comparers durcheinandergeraten.

Hier ein Comparer, der beim Sortieren ggf. die NaN-Werte an das Ende des Arays rückt. (Beim Vergleich eines gültigen Doublewertes mit einem NaN-Wert wird der Nan-Wert vom 'DoubleComparer' stets als der relativ größere Wert angegeben.)

Der Rechenzeitbedarf für das Sortieren großer Arrays liegt bei Anwendung des 'DoubleComparers' etwa 3x höher - im Vergleich zum Bedarf bei Verwendung des StandardComparers - und zwar unabhängig davon, ob und wie viele NaN.Werte im Array vorliegen.

Grundsätzlich ist bei der Programmierung eines 'Comparers' für Sortierfunktionen zu beachten, dass bei sukzessiver Anwendung keine widersprüchlichen Vergleichs-Ergebnisse auftreten dürfen (also etwa: a > b, b > c, c > a).

Als (langsame und etwas umständliche) Alternative bietet sich die OrderBy-Methode der Enumerable-Klasse an (Namespace: System.Linq.Enumerable). Dieses Verfahren sortiert NaN-Werte an den Anfang des Array, falls man als Parameter die sogenannte 'Identitätsfunktion' verwendet. Auch hier ist es möglich, eine selbsterstellte Comparer-Klasse für den Vergleich beim Sortieren anzugeben./p>

Aufrufbeispiele:

Randomize(1000.0#)
 
' Array erstellen
Dim n As Integer = 25
Dim arr(n) As Double
 
' Array mit Zufallswerten füllen
Fill(arr)
 
' einige Sonderwerte zuweisen
arr(5) = Double.PositiveInfinity
arr(8) = Double.MaxValue
arr(10) = Double.NaN
arr(20) = Double.NegativeInfinity
arr(22) = Double.NaN
arr(25) = Double.MinValue
 
Array.Sort(arr, New DoubleComparer)
 
arr = arr.AsEnumerable.OrderBy _
  (Of Double)(Function(arg) arg).ToArray()
 
arr = arr.AsEnumerable.OrderBy _
  (Of Double)(Function(arg) arg, New DoubleComparer).ToArray()

Und hier die Comparer-Klasse:

Public Class DoubleComparer
  Implements IComparer(Of Double)
 
  Public Function Compare(ByVal x As Double, _
    ByVal y As Double) As Integer _
    Implements IComparer(Of Double).Compare
 
    ' NaN-Wert?
    Dim is_x_undef As Boolean = Double.IsNaN(x)
    Dim is_y_undef As Boolean = Double.IsNaN(y)
 
    ' Vergleich durchführen 
    If is_x_undef And is_y_undef Then
      Return 0
    ElseIf is_x_undef Then
      Return 1
    ElseIf is_y_undef Then
      Return -1
    ElseIf x = y Then
      Return 0
    ElseIf x > y Then
      Return 1
    Else
      Return -1
    End If
  End Function
End Class

Zwei Hilfsfunktionen:

Public Sub Fill(Of T)(ByRef D1arr As T())
  For i As Integer = 0 To D1arr.GetUpperBound(0)
    D1arr(i) = CType(Convert.ChangeType(RandomNumber, GetType(T)), T)
  Next i
End Sub
Public Function RandomNumber() As Double
  Dim r As Double = Microsoft.VisualBasic.Rnd
  If Microsoft.VisualBasic.Rnd < 0.5 Then r *= -1
  Return r
End Function

Dieser Tipp wurde bereits 7.074 mal aufgerufen.

Voriger Tipp   |   Zufälliger Tipp   |   Nächster Tipp

Über diesen Tipp im Forum diskutieren
Haben Sie Fragen oder Anregungen zu diesem Tipp, können Sie gerne mit anderen darüber in unserem Forum diskutieren.

Aktuelle Diskussion anzeigen (1 Beitrag)

nach obenzurück


Anzeige

Kauftipp Unser Dauerbrenner!Diesen und auch alle anderen Tipps & Tricks finden Sie auch auf unserer aktuellen vb@rchiv  Vol.6

Ein absolutes Muss - Geballtes Wissen aus mehr als 8 Jahren vb@rchiv!
- nahezu alle Tipps & Tricks und Workshops mit Beispielprojekten
- Symbol-Galerie mit mehr als 3.200 Icons im modernen Look
Weitere Infos - 4 Entwickler-Vollversionen (u.a. sevFTP für .NET), Online-Update-Funktion u.v.m.
 
   

Druckansicht Druckansicht Copyright ©2000-2018 vb@rchiv Dieter Otter
Alle Rechte vorbehalten.
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein.

Diese Seiten wurden optimiert für eine Bildschirmauflösung von mind. 1280x1024 Pixel