- Offizieller Beitrag
Ich habe mal eine UDF erstellt mit der man Zufallszahlen generieren kann.
Eigenschaften:
- Die Zufallszahlen sind einmalig, kommen also nur ein Mal vor
- Ausgabe aufsteigend sortiert ausgeben lassen
- Zahlenbereich auswählbar
- Anzahl der Zufallszahlen auswählbar
- Ganz- oder Kommazahlen möglich
Version 1.4.0.0 ( 23.06.08 )
Edit 1.3.0.0 :
Jetzt kann man auch riesige Zahlenbereiche angeben, wie z.B. 10.000 Zufallszahlen aus dem Bereich 100.000.000...999.999.999, aufsteigend sortiert ausgeben. Auf meinem Rechner braucht das Script dafür nur rund 4 sek. Man bedenke: es gibt dabei keine doppelten Zahlen!
Edit 1.4.0.0 :
- Parameterübergabe an die Original Random()-Funktion angepasst (siehe Kommentare in der UDF)
- Auswahlmöglichkeit (Ganz- oder Kommazahlen)
Mein besonderer Dank gilt hierbei: BugFix, der mit seiner Erklärung zu dem Dictionary-Objekt zu diesen Erfolg beigetragen hat.
BugFix : Ich benutze das Objekt zwar 'nur' um die doppelten auszuschliessen, aber mit anderen Mitteln würde das ewig dauern.
Das ist die UDF:
Spoiler anzeigen
#include-once
;===============================================================================
; Funktion Name: _RanNumGen()
; AutoIt-Version: 3.2.10.0
; Language: German
; Version: 1.4.0.0
; Date: 23. Jun. 2008
; Author: Thomas Stephan <oscar at elektronik-kurs dot de>
;
; Beschreibung:
; Diese Funktion generiert Zufallszahlen aus einem angegebenen Zahlenbereich.
; Die ausgegebenen Zufallszahlen sind einmalig, kommen also nicht doppelt vor.
; Sortierung erfolgt mit einer Quicksort-Version
;
; Funktionsaufruf: _RanNumGen ( [$min], [$max], [$int], [$num], [, $sort] )
; [$min] und [$max] = Anfang (Default = 0) und Ende (Default = 1) des Zahlenbereichs
; [$int] = Ganzzahl (True) oder Kommazahl (False = Default)
; [$num] = Anzahl der auszugebenen Zufallszahlen
; Wenn $num nicht angegeben ist, dann nur eine Zahl generieren
; [$sort] = 'True', Ausgabe wird aufsteigend sortiert (wird ignoriert bei $num = 1)
; [$sort] = 'False' oder nicht angegeben, dann unsortiert
;
; Rückgabe:
; Wenn keine Fehler aufgetreten sind, wird ein 0-basiertes Array mit den
; Zufallszahlen zurückgegeben.
;
; Bei einem Fehler ist der Rückgabewert = 0 und @error =
; 1 = Wenn $num (Anzahl der Zufallszahlen) Null oder negativ
; 2 = Wenn $max kleiner als $min
; 3 = Wenn $num (Anzahl der Zufallszahlen) größer als
; der Zahlenbereich ($min bis $max)
; 4 = Dictionary-Objekt konnte nicht erstellt werden
;===============================================================================
Func _RanNumGen($min = 0, $max = 1, $int = False, $num = 1, $sort = False)
If $num < 1 Then Return SetError(1, 0, 0)
If $max < $min Then Return SetError(2, 0, 0)
If $num > $max - $min + 1 Then Return SetError(3, 0, 0)
$oDictionary = ObjCreate('Scripting.Dictionary')
If Not IsObj($oDictionary) Then Return SetError(4, 0, 0)
SRandom(@AutoItPID + @SEC + @MIN + @HOUR + @YDAY + @YEAR)
Local $out[$num], $ran, $i
For $i = 0 To $num-1
Do
$ran = Random($min, $max, $int)
Until Not $oDictionary.Exists($ran)
$oDictionary.Add($ran, '')
$out[$i] = $ran
Next
$oDictionary.RemoveAll
If $sort And ($num > 1) Then _Quicksort($out, 0, $num-1)
Return $out
EndFunc
Func _Quicksort(ByRef $aArray, $left, $right)
If $left < $right Then
Local $pivot = _SplitSwap($aArray, $left, $right)
_Quicksort($aArray, $left, $pivot-1)
_Quicksort($aArray, $pivot+1, $right)
EndIf
EndFunc
Func _SplitSwap(ByRef $aArray, $left, $right)
Local $i = $left, $j = $right-1, $pivot = $aArray[$right], $h
Do
While $aArray[$i] <= $pivot And $i < $right
$i += 1
WEnd
While $pivot <= $aArray[$j] And $j > $left
$j -= 1
WEnd
If $i < $j Then
$h = $aArray[$i]
$aArray[$i] = $aArray[$j]
$aArray[$j] = $h
EndIf
Until $i >= $j
$aArray[$right] = $aArray[$i]
$aArray[$i] = $pivot
Return $i
EndFunc
Und das ist ein Beispielscript:
Spoiler anzeigen
#include <Array.au3> ; wird hier nur für die Anzeige benötigt
#include "RanNumGen.au3" ; wenn die UDF im Script-Verzeichnis liegt
; #include <RanNumGen.au3> ; wenn die UDF im Include-Verzeichnis (C:\Programme\AutoIt3\Include) liegt.
; <Anfang> Beispielaufruf mit Ausgabe
; ------------------------------------------------------------------------------
; Beispiel 1 = 1.000 Kommazahlen aus dem Bereich 1.000.000.000...2.147.483.647 (2^31-1 ist das Maximum), aufsteigend sortiert ausgeben
Global $zahlen = _RanNumGen(1000000000, 2147483647, 0, 1000, True)
If IsArray($zahlen) Then _ArrayDisplay($zahlen)
; Beispiel 2 = 6 Ganzzahlen aus dem Bereich 1...49, aufsteigend sortiert ausgeben
Global $zahlen = _RanNumGen(1, 49, 1, 6, True)
If IsArray($zahlen) Then _ArrayDisplay($zahlen)
; ------------------------------------------------------------------------------
; <Ende> Beispielaufruf
Vielleicht kann es ja noch jemand gebrauchen.