ABOUT Visual Basic Programmieren Programmierung Download Downloads Tips & Tricks Tipps & Tricks Know-How Praxis VB VBA Visual Basic for Applications VBS VBScript Scripting Windows ActiveX COM OLE API ComputerPC Microsoft Office Microsoft Office 97 Office 2000 Access Word Winword Excel Outlook Addins ASP Active Server Pages COMAddIns ActiveX-Controls OCX UserControl UserDocument Komponenten DLL EXE
Diese Seite wurde zuletzt aktualisiert am 12.11.2001

Diese Seite wurde zuletzt aktualisiert am 12.11.2001
Aktuell im ABOUT Visual Basic-MagazinGrundlagenwissen und TechnologienKnow How, Tipps und Tricks rund um Visual BasicActiveX-Komponenten, Controls, Klassen und mehr...AddIns für die Visual Basic-IDE und die VBA-IDEVBA-Programmierung in MS-Office und anderen AnwendungenScripting-Praxis für den Windows Scripting Host und das Scripting-ControlTools, Komponenten und Dienstleistungen des MarktesRessourcen für Programmierer (Bücher, Job-Börse)Dies&Das...

Themen und Stichwörter im ABOUT Visual Basic-Magazin
Code, Beispiele, Komponenten, Tools im Überblick, Shareware, Freeware
Ihre Service-Seite, Termine, Job-Börse
Melden Sie sich an, um in den vollen Genuss des ABOUT Visual Basic-Magazins zu kommen!
Informationen zum ABOUT Visual Basic-Magazin, Kontakt und Impressum

Zurück...

Desortierer

Zurück...


Anzeige

(-hg) mailto:hg_arrayrandomize@aboutvb.de

Es gibt eine ganze Reihe verschiedener Algorithmen zum Sortieren eines Datenfeldes (Arrays), vom Bubblesort- bis zum Quicksort-Algorithmus, oder wie sie alle heißen mögen. Sie werden sicher schnell im Internet fündig, wenn Sie einmal nach einer entsprechenden Umsetzung in Visual Basic suchen. Gute Lösungen für den umgekehrten Weg, nämlich die Elemente eines wohlsortierten Arrays (wieder) in eine garantiert ungeordnete, zufällige Reihenfolge zu bringen, sind dagegen ziemlich selten anzutreffen. Wozu das gut sein soll, fragen Sie? Nun, es mag den einen oder anderen Grund geben - aber ich halte es einfach mal so: Hier finden Sie die Lösung, und die Suche nach dem passenden Problem ist Ihr Bier...

Das "Desortier"-Prinzip ist einfach. Wir können schließlich davon ausgehen, dass die Anzahl der Elemente des Ausgangs-Arrays und des Ziel-Arrays übereinstimmen. Wir nehmen uns also jedes Element des Ausgangs-Arrays vor und versuchen, es an eine andere Stelle im Ziel-Arrays, deren Index wir jeweils zufällig ermitteln (siehe Wie der Zufall es will"Wie der Zufall es will"), zu stecken. Ist dort noch kein Element abgelegt, nehmen wie die Neuzuweisung vor, anderenfalls lassen wir den Zufallszahlengenerator so lange nach einem freien Index suchen, bis einer gefunden ist. Letzteres dauert natürlich um so länger, je mehr das Ziel-Array bereits gefüllt ist, weil damit ja zwangsläufig die Anzahl der Fehlversuche zunehmend steigt. Die letzten freien Stellen zu finden kann unter Umständen relativ lange dauern - kritisch wird es meinen Versuchen zufolge aber erst ab Array-Größen von mehreren hundertausend Elementen. Es gibt meines Wissens kein verkürzendes Verfahren, bei dem etwa der dem Zufall zur Verfügung stehende Suchraum kontinuierlich eingeschränkt würde, und das sich in Visual Basic tatsächlich Performance gewinnend implementieren ließe.

Ob eine Stelle im Ziel-Array belegt ist, lässt sich bei String-Arrays prüfen, indem mittels der (undokumentierten) VB-Funktion StrPtr der Initialisierungszustand des betreffenden Elements geprüft wird. Liefert StrPtr den Wert 0, ist dem Element noch kein String-Wert zugewiesen worden.

Public Function ArrayRandomizeStr(Arr() As String) As Variant
  Dim nLBound As Long
  Dim nUBound As Long
  Dim nNewArr() As String
  Dim l As Long
  Dim nNewIndex As Long
  Dim nRndArg As Long
  
  nLBound = LBound(Arr)
  nUBound = UBound(Arr)
  ReDim nNewArr(nLBound To nUBound)
  Randomize Timer
  nRndArg = nUBound - nLBound + 1
  For l = nLBound To nUBound
    Do
      nNewIndex = Int(nRndArg * Rnd + nLBound)
    Loop While StrPtr(nNewArr(nNewIndex))
    nNewArr(nNewIndex) = Arr(l)
  Next 'l
  ArrayRandomizeStr = nNewArr
End Function

Bei Arrays aller anderen Datentypen ist eine solche Prüfung des "jungfräulichen" Zustands eines Elements leider nicht möglich. Daher benötigen wir bei diesen ein zusätzliches Array des Typs Boolean in gleicher Größe, in dem die Belegung einer Stelle markiert wird. Hier sehen Sie nun (stellvertretend) die Funktion für Arrays des Datentyps Long:

Public Function ArrayRandomizeLong(Arr() As Long) As Variant
  Dim nLBound As Long
  Dim nUBound As Long
  Dim nNewArr() As Long
  Dim nNewArrFlags() As Boolean
  Dim l As Long
  Dim nNewIndex As Long
  Dim nRndArg As Long
  
  nLBound = LBound(Arr)
  nUBound = UBound(Arr)
  ReDim nNewArr(nLBound To nUBound)
  ReDim nNewArrFlags(nLBound To nUBound)
  Randomize Timer
  nRndArg = nUBound - nLBound + 1
  For l = nLBound To nUBound
    Do
      nNewIndex = Int(nRndArg * Rnd + nLBound)
    Loop While nNewArrFlags(nNewIndex)
    nNewArr(nNewIndex) = Arr(l)
    nNewArrFlags(nNewIndex) = True
  Next 'l
  ArrayRandomizeLong = nNewArr
End Function

Falls Sie bei einem String-Array den kleinen Trick mit der StrPtr-Funktion nicht nutzen können, weil auch in dem Ausgangs-Array schon nicht initialisierte Elemente enthalten sein könnten, können Sie das allgemeinere Verfahren für die übrigen Datentypen mit der Markierung in einem Boolean-Array auch für Strings adaptieren:

Public Function ArrayRandomizeStr2(Arr() As String) As Variant
  Dim nLBound As Long
  Dim nUBound As Long
  Dim nNewArr() As String
  Dim nNewArrFlags() As Boolean
  Dim l As Long
  Dim nNewIndex As Long
  Dim nRndArg As Long
  
  nLBound = LBound(Arr)
  nUBound = UBound(Arr)
  ReDim nNewArr(nLBound To nUBound)
  ReDim nNewArrFlags(nLBound To nUBound)
  Randomize Timer
  nRndArg = nUBound - nLBound + 1
  For l = nLBound To nUBound
    Do
      nNewIndex = Int(nRndArg * Rnd + nLBound)
    Loop While nNewArrFlags(nNewIndex)
    nNewArr(nNewIndex) = Arr(l)
    nNewArrFlags(nNewIndex) = True
  Next 'l
  ArrayRandomizeStr2 = nNewArr
End Function

Aber eigentlich ist das nicht notwendig. Denn am Ende bleiben auch im Ziel-Array genau so viele Elemente uninitialisiert, wie im Ausgangs-Array vorhanden waren.


Modul modArrayRandomize (modArrayRandomize.bas - ca. 2,2 KB)


Artikel
Zum Download-Bereich dieses Artikel
Mail an den Autor dieses Artikels

KnowHow
Zur KnowHow-Übersicht

KnowHow-Themen
Themen - Allgemeines
Themen - Entwicklungsumgebung (VB-IDE)
Themen - Forms
Themen - Steuerelemente (Controls)
Themen - Grafik
Themen - Dateien
Themen - UserControls
Themen - Einsteiger-Tipps
Themen - Wussten Sie...?

Übersicht nach Titeln in alphabetischer Reihenfolge
Übersicht nach Erscheinungsdatum

Schnellsuche




Zum Seitenanfang

Copyright © 1999 - 2017 Harald M. Genauck, ip-pro gmbh  /  Impressum

Zum Seitenanfang

Zurück...

Zurück...

Download Internet Explorer