AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Zufallszahl ziehen ohne wiederholung

Offene Frage von "walli18"
Ein Thema von walli18 · begonnen am 6. Feb 2009 · letzter Beitrag vom 17. Feb 2009
Antwort Antwort
Seite 3 von 7     123 45     Letzte »    
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.034 Beiträge
 
Delphi 12 Athens
 
#21

Re: Zufallszahl ziehen ohne wiederholung

  Alt 7. Feb 2009, 09:06
Zitat von blink182:
hab auch mal eben noch was getestet, ist wahrscheinlich nicht so gut wie der oben gepostete code, da es nach 40 klicks eine endlosschleife gibt, aber das kannst du ja noch beheben
die Endlosschleife wär ja noch nichtmal das Schlimmste

for i:=0 to length(zufall) do hier eine Exception (wenn du mal die Bereichsprüfung anschaltes)

a:=random(39); die 40 (Index 39) gibt's nicht, da 0..38

zufall: array of integer; OK, kein Fehler, aber der Index is die Zahl-1, da braucht man nicht unbedingt ein Array of Integer ... Array of Boolean hätt's auch getan,
denn die zugehörige Zahl kann man sich ja aus dem Index errechnen.
PS: bei Array[1..40] of Boolean wär der Index direkt die Zahl
If MeinZahlenArray[gezogeneZahl] Then {zahl wurde gezogen}
oder gleich ein Set of 1..40
Delphi-Quellcode:
Var gezogeneZahlen: Set of 1..40;
  Zufallszahl: Integer;

gezogeneZahlen := []; // init

If gezogeneZahlen <> [1..40] Then Begin
  Repeat
    Zufallszahl := Random(40) + 1;
  Until not (Zufallszahl in gezogeneZahlen);
  Include(gezogeneZahlen, Zufallszahl);
End Else Raise Exception.Create('Es gibt keine Zahlen mehr.');
MessageBox(0, PChar(Format('Die Zahl %d wurde soeben gezogen.',
  [Zufallszahl])), 'test', MB_OK);
Delphi-Quellcode:
Var gezogeneZahlen: Set of 1..40;
  Zufallszahl, i: Integer;

gezogeneZahlen := [];
For i := 1 to 15 do Begin
  Repeat
    Zufallszahl := Random(40) + 1;
  Until not (Zufallszahl in gezogeneZahlen);
  Include(gezogeneZahlen, Zufallszahl);
  MessageBox(0, PChar(Format('Die %d. Zahl ist eine %d.',
    [i, Zufallszahl])), 'test', MB_OK);
End;
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
globetrotter77

Registriert seit: 16. Jan 2009
Ort: Nürnberg
236 Beiträge
 
Delphi 10.3 Rio
 
#22

Re: Zufallszahl ziehen ohne wiederholung

  Alt 7. Feb 2009, 10:13
Wenn's nicht mehr als 255 Fragen sein sollen, könnte man auch eine Lösung mit einem String basteln.
Das sieht dann so aus:
Stelle 1 = #1
Stelle 2 = #2
etc.
Nach jedem Ziehen wird das gezogene Zeichen aus dem String gelöscht.

beispielsweise so:
Delphi-Quellcode:
const gesamt=40;
      anzahl=15;
var liste: string;

procedure TForm1.FormCreate(Sender: TObject);
var i:integer;
begin
  Randomize;
  liste:='';
  for i:=1 to gesamt do
    liste:=liste+chr(i);
end;

procedure TForm1.Button1Click(Sender: TObject);
var p,z:integer;
begin
  if length(liste)<=gesamt-anzahl then
  begin
    showmessage('Fertig!');
    exit;
  end;
  p:=Random(length(liste))+1;
  z:=ord(liste[p]);
  delete(liste,p,1);
  frage(z);
end;

procedure TForm1.frage(z: integer);
begin
  ListBox1.Items.Add(IntToStr(z)); // hier sollte natürlich die eigentliche Frage
                                   // mit der Nr. z bearbeitet werden
end;
Zitat:
hatte bisschen Langeweile und hab das ganze mal zu Übungszwecken (und zur Verwirrung) absichtlich bisschen komplexer gelöst *g*
ein sehr hübscher Ansatz! ... *grins*
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.034 Beiträge
 
Delphi 12 Athens
 
#23

Re: Zufallszahl ziehen ohne wiederholung

  Alt 7. Feb 2009, 10:24
@globetrotter77: mit WideString/UnicodeString ginge das bis 65536

und mit einem "eigenem" Delete ginge das noch viel weiter, wobei man da auch direkt die Fragen/Antworten direkt in das array packen kann,
oder da zusätzlich noch einen Benutzt-Boolean in das Array of Record und man braucht garnicht löschen.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
walli18

Registriert seit: 29. Jan 2009
21 Beiträge
 
#24

Re: Zufallszahl ziehen ohne wiederholung

  Alt 7. Feb 2009, 10:41
@ Globetrotter!
deine Antwort fand ich bis jetzt am besten, da sie für mich einigermaßen verständlich war!
ich weiß nur nicht, wo ich den teil mit
Delphi-Quellcode:
const gesamt=40;
      anzahl=15;
[b]hinpacken soll bei der deklaration!? Public, Private??
  Mit Zitat antworten Zitat
globetrotter77

Registriert seit: 16. Jan 2009
Ort: Nürnberg
236 Beiträge
 
Delphi 10.3 Rio
 
#25

Re: Zufallszahl ziehen ohne wiederholung

  Alt 7. Feb 2009, 10:43
Zitat von himitsu:
@globetrotter77: mit WideString/UnicodeString ginge das bis 65536

und mit einem "eigenem" Delete ginge das noch viel weiter, wobei man da auch direkt die Fragen/Antworten direkt in das array packen kann,
oder da zusätzlich noch einen Benutzt-Boolean in das Array of Record und man braucht garnicht löschen.
Für den Anfang dürften die 255 bzw. 65535 (!) aber ausreichen!
Das mit dem Benutzt-Kennzeichen funktioniert aber nicht ganz so gut, weil du dann zumindest theoretisch in eine Endlosschleife kommen könntest.

Die Fragen würde ich von außen über eine INI beisteuern.
z.B.
Zitat:
[Frage3]
Frage:=Wann war die russische Oktoberrevolution?
A=1919
B=1920
C=1917
D=1918
Lösung=3
Dann lässt sich das Ganze ganz einfach einheitlich mit Radiobuttons o.ä. darstellen.
  Mit Zitat antworten Zitat
globetrotter77

Registriert seit: 16. Jan 2009
Ort: Nürnberg
236 Beiträge
 
Delphi 10.3 Rio
 
#26

Re: Zufallszahl ziehen ohne wiederholung

  Alt 7. Feb 2009, 10:47
Zitat von walli18:
@ Globetrotter!
deine Antwort fand ich bis jetzt am besten, da sie für mich einigermaßen verständlich war!
ich weiß nur nicht, wo ich den teil mit
Delphi-Quellcode:
const gesamt=40;
      anzahl=15;
[b]hinpacken soll bei der deklaration!? Public, Private??
Du kannst sie sowohl im Public als auch im Private-Bereich unterbringen.
Da es sich aber um ganz einfache Definitionen handelt, die nicht unbedingt was mit der Klasse zu tun haben, geht es ebenso im implementation-Bereich, wobei du nur darauf achten musst, dass die Definition OBERHALB derjenigen Funktionen und Prozeduren steht, die darauf zugreifen!

z.B. so:
Delphi-Quellcode:
var
  Form1: TForm1;

implementation

{$R *.DFM}

const gesamt=40;
      anzahl=15;

var liste: string;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Randomize;
  ButtonNeuClick(Sender);
end;
  Mit Zitat antworten Zitat
walli18

Registriert seit: 29. Jan 2009
21 Beiträge
 
#27

Re: Zufallszahl ziehen ohne wiederholung

  Alt 7. Feb 2009, 11:03
Danke Globetrotter, mit deiner Variante hab ichs hinbekommen!!!
  Mit Zitat antworten Zitat
globetrotter77

Registriert seit: 16. Jan 2009
Ort: Nürnberg
236 Beiträge
 
Delphi 10.3 Rio
 
#28

Re: Zufallszahl ziehen ohne wiederholung

  Alt 7. Feb 2009, 11:12
Zitat von walli18:
Danke Globetrotter, mit deiner Variante hab ichs hinbekommen!!!
Gern geschehen!
Versuch aber auf jeden Fall, genau zu verstehen, wieso das so funktioniert!
Sonst stehst du da nächste Mal wieder da wie der Ochs vor dem Berg!
  Mit Zitat antworten Zitat
Benutzerbild von juergen
juergen

Registriert seit: 10. Jan 2005
Ort: Bönen
1.174 Beiträge
 
Delphi 11 Alexandria
 
#29

Re: Zufallszahl ziehen ohne wiederholung

  Alt 7. Feb 2009, 11:41
Hallo zusammen,

auch wenn es schon Lösungen gibt, so möchte ich für die genannte Anforderung auf die Umsetzung in Form eines boolschen Array hinweisen.
Für einen Lottogenerator hatte ich es mal wie nachfolgend zu sehen umgesetzt.

Delphi-Quellcode:
procedure TForm1.Btn1Click(Sender: TObject);
var lAb_Anzahl_Werte_Depot: Array[1..49] of Boolean;
     i, Zufallszahl: Integer;
begin
  for i:= 1 to 49 do lAb_Anzahl_Werte_Depot[i]:=false;
  for i:=1 to 6 do begin
   repeat
    Zufallszahl:=random(49)+1
   until lAb_Anzahl_Werte_Depot[Zufallszahl] = false;
   lAb_Anzahl_Werte_Depot[Zufallszahl]:=true;
  end;
  Edit1.Text:='';
  for i:=1 to 49 do
   if lAb_Anzahl_Werte_Depot[i] then Edit1.Text:= Edit1.Text + ' ' + Inttostr(i) + ' ';
end;
Hiermit hat man die 2 Eigenschaften welche benötigt werden (Anzahl von Werten und den boolschen Wert ob schon "gezogen" oder nicht).
Jürgen
Indes sie forschten, röntgten, filmten, funkten, entstand von selbst die köstlichste Erfindung: der Umweg als die kürzeste Verbindung zwischen zwei Punkten. (Erich Kästner)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.034 Beiträge
 
Delphi 12 Athens
 
#30

Re: Zufallszahl ziehen ohne wiederholung

  Alt 7. Feb 2009, 12:43
Zitat von globetrotter77:
Für den Anfang dürften die 255 bzw. 65535 (!) aber ausreichen!
65536, denn in Delphi-Strings kann man auch die #0 benutzen

Zitat von globetrotter77:
Das mit dem Benutzt-Kennzeichen funktioniert aber nicht ganz so gut, weil du dann zumindest theoretisch in eine Endlosschleife kommen könntest.
das kommt darau an, wie du die Abfrage gestaltest.
Delphi-Quellcode:
i := -1;
for i2 := 1 to 40
  if not meinArray[i2].istSchonBenutzt then begin
    i := i2;
    break;
  end;
if i <> -1 then begin
  meinArray[i].isSchonBenutzt := true;
  ShowMessage('Zahl ', i, ' wurde gezogen.');
end else nichts_mehr_frei;
oder besser noch 'nen knuffiges While-Do-Schleifchen
Delphi-Quellcode:
i := 1;
while (i <= 40) and meinArray[i].istSchonBenutzt do Inc(i);
if i <= 40 then begin
  meinArray[i].isSchonBenutzt := true;
  ShowMessage('Zahl ', i, ' wurde gezogen und die Frage is "', meinArray[i].dieFrage, '".');
end else nichts_mehr_frei;
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 3 von 7     123 45     Letzte »    


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:48 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz