![]() |
Zufällig Zahlen ziehen, aber ohne Wiederholung
Hier eine Klasse, die zufällig Zahlen aus einem Zahlenbereich zieht, bis keine mehr übrig sind. Jede Zahl wird nur 1x gezogen. Die Klasse erstellt eine Liste der Zahlen, mischt sie nach Fisher-Yates und liefert dann eine nach dem anderen zurück.
Verwendung (Lotto, 6 aus 49 + Zusatzzahl);
Delphi-Quellcode:
Und hier die Klasse:
With TUniqueRandomSequenceGenerator.Create (1,49) do begin
Write('Und hier die Lottozahlen: '); For i := 1 to 6 do Write(GetNextNumber:2,' '); Writeln(' Zusatzzahl ',GetNextNumber); Free End;
Delphi-Quellcode:
[edit]Schlampenfehler dank gsammatester korrigiert[/edit]
type
ENoMoreNumbers = Exception; TUniqueRandomSequenceGenerator = class private FCounter: Integer; FNumberList: array of Integer; procedure BuildSequence(aStart, aEnde: Integer); public constructor Create(aStart, aEnde: Integer); function GetNextNumber: Integer; function TotalCount: Integer; function RemainingCount: Integer; end; implementation { TUniqueRandomGenerator } constructor TUniqueRandomSequenceGenerator.Create(aStart, aEnde: Integer); begin BuildSequence(aStart, aEnde); end; procedure TUniqueRandomSequenceGenerator.BuildSequence(aStart, aEnde: Integer); var i, j, tmp: Integer; begin SetLength(FNumberList, aEnde - aStart + 1); // Zahlenliste erzeugen for i := 0 to TotalCount - 1 do FNumberList[i] := aStart + i; // Mischen nach Fisher-Yates for i := Low(FNumberList) to High(FNumberList) do begin j := i + Random(TotalCount - i); tmp := FNumberList[j]; FNumberList[j] := FNumberList[i]; FNumberList[i] := tmp; end; FCounter := 0; end; function TUniqueRandomSequenceGenerator.GetNextNumber: Integer; begin if FCounter < TotslCount then begin Result := FNumberList[FCounter]; Inc(FCounter); end else raise ENoMoreNumbers.Create('No more numbers'); end; function TUniqueRandomSequenceGenerator.RemainingCount: Integer; begin Result := TotalCount - FCounter; end; function TUniqueRandomSequenceGenerator.TotalCount: Integer; begin Result := Length(FNumberList); end; |
Re: Zufällig Zahlen ziehen, aber ohne Wiederholung
Also mit Delphi 2 und/oder 3 kann man's nicht übersetzen, da zB keine dynamischen Arrays bekannt sind.
Dann ein Bug: '<' muss durch '<=" ersetzt werden, sonst erhält man nicht die gesamte Liste (das berüchtigte 1-mehr/weniger-Problem):
Delphi-Quellcode:
Aus Konsistenzgünden sollte statt Length(FNumberList) hier
function TUniqueRandomSequenceGenerator.GetNextNumber: Integer;
begin if FCounter <= High(FNumberList) then begin // hier <= statt < Result := FNumberList[FCounter]; Inc(FCounter); end else raise ENoMoreNumbers.Create('No more numbers'); end;
Delphi-Quellcode:
auch TotalCount benutzt werden,
j := i + Random(Length(FNumberList) - i);
Gruß Gammatester |
Re: Zufällig Zahlen ziehen, aber ohne Wiederholung
Zitat:
|
Re: Zufällig Zahlen ziehen, aber ohne Wiederholung
Zitat:
Klaus |
Re: Zufällig Zahlen ziehen, aber ohne Wiederholung
Hi gammatester,
wenn Du nicht wärst.... :thumb: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:10 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz