Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Zufallszahlen


klabri - Do 30.10.08 00:43
Titel: Zufallszahlen
Hallo
ich bin der absolute Delphi-Anfänger ; kann mir mal jemand
helfen ?


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
for i:=1 to 20 do 
begin 
j:= i;
z:=random(30)+1;   //Zufallszahl ziehen 
A[i]:=z;           // im Array speichern 
if i> 1 then       // 
      for j:=i-1 downto 1   
      begin              // gibt es die Zahl schon ?
      if a[j]=a[i] then  //  wenn Zahl schon da   
          
 z:=random(30)+1;        // ziehe Zahl neu 
            a[i]:= z;
            end;  
end;

-Es gibt ein Array mit Zufallszahlen
-doppelte Zahlen sollen ausgeschlossen werden
-bei if a[j]=a[i] funktioniert etwas nicht
hat jemand ein Tipp ?

Moderiert von user profile iconKha: Delphi-Tags hinzugefügt


Yogu - Do 30.10.08 00:49

Hallo und :welcome: im Delphi-Forum, user profile iconklabri!

Bitte benutze für Delphi-Codes in Zukunft die Delphi-Tags (<span class="inlineSyntax"><span class="codecomment">{PROTECTTAGf25012a56b63a07d0555ecbcedb7c37b}</span></span>).


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
for i :=1 to 20 do
begin
  j := i;
  z := Random(30) + 1; //Zufallszahl ziehen
  A[i] := z; // im Array speichern
  if i > 1 then //
    for j := i-1 downto 1
    begin // gibt es die Zahl schon ?
      if a[j] = a[i] then // wenn Zahl schon da
        z := Random(30) + 1; // ziehe Zahl neu
      a[i] := z;
    end;
end;

Da fehlt ein begin ... end, oder? ;) Außerdem musst du das ganze in eine Schleife packen, es könnte ja zweimal hintereinander die gleiche Zahl gezogen werden:


Delphi-Quelltext
 
7:
8:
9:
10:
11:
12:
13:
14:
{ ... }
for j := i-1 downto 1
begin // gibt es die Zahl schon ?
  while a[j] = a[i] do // wenn Zahl schon da
  begin
    z := Random(30) + 1; // ziehe Zahl neu
    a[i] := z;
  end;
end;


GTA-Place - Do 30.10.08 09:28

Nein, nein, das geht so nicht. Beispiel:

- 1 8 4 3 5 und die neue Zahl wäre 8
- wir kommen zur Stelle j = 2, wo A[j] = 8
- neue Zufallszahl: 5
- wir kommen zur Stelle j = 1, wo A[j] <> 5
- fertig: 1 8 4 3 5 5

Fehler erkannt?


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
for i := 1 to 20 do  
begin   
  found := True;

  while found do
  begin
    found := False;
    z := Random(30) + 1;

    for j := i - 1 downto 1 do
      if a[j] = a[i] then
        found := True;
  end;

  a[i] := z;
end;

Neuer Ablauf:

- 1 8 4 3 5 und die neue Zahl wäre 8
- wir kommen zur Stelle j = 2, wo A[j] = 8
- neue Zufallszahl: 5
- wir beginnen erneut von vorne
- wir kommen zur Stelle j = 5, wo A[j] = 5
- neue Zufallszahl: 7
- wir beginnen erneut von vorne
- fertig: 1 8 4 3 5 7


oldmax - Do 30.10.08 15:55

Hi
Wenn du dir eine evtuelle Endlosschleife, weil sich nach der 5. Zahl rein Zufällig immer wieder die bereits gezogenen Werte ergeben, ersparen willst, schreibe die Zahlen von 1- max. ( in deinem Fll 30 ) in eine Stringlist. Das sie sortiert sind, braucht dich nicht zu interessieren, denn mit der Zufallszahl greifst du auf einen Eintrag zu und erhälst die darin abgelegte Zahl. Den Eintrag löschst du aus der Liste und reduzierst deine max. Zufallszahl. So können keine doppelten Zahlen vorkommen.


Delphi-Quelltext
1:
Var MyStringList   : TStringlist;  // gehört zu den Variablendeklarationen                    


Stringlist füllen:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
MyStringList:=TStringlist.Create;  // Wenn global, dann nur 1x erstellen
   // das hier geht öfter
MyStringlist.Clear;
For i:=1 to 30 do MyStringlist.Items.Add(IntToStr(i)); // i in einen String wandeln

//nun die Zufallszahlen ermitteln, bzw. in eine 2. Stringlist übertragen

MyErgebnis.Items.Clear;

MyStringList:=TStringlist.Create;  // MyStringlist wird deklariert vom Typ TStringlist
for i:=1 to 20 do   
begin   
  Max := MyStringlist.Count-1;
  Z:=random(Max);   //Zufallszahl ziehen   
  A[i]:=StrToInt(MyStringlist[z]);   // im Array speichern   
  // oder
  MyErgebnis.Items.Add(MyStringList[i]);  //TListbox
  // nun den Eintrag entfernen
  MyStringlist.Delete(i);
  
end;


Gruß oldmax


Yogu - Do 30.10.08 18:20

user profile iconoldmax: Gute Idee, aber doch bitte nicht in einer StringList speichern :!:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
function GetRandomValues(MaxValue {=30}, ValueCount {=20}: Integer): TIntegerArray;
var Values: array of Integer; i, Index: Integer;
begin
  // Quellenarray füllen
  SetLength(Values, MaxValue);
  for i := Low(Values) to High(Values) do Values[i] := i+1;

  // Zielarraygröße setzen
  SetLength(Result, ValueCount);
  
  for i := Low(Result) to High(Result) do
  begin
    // Zufallszahl berechnen (0..AnzahlVerbleibende-1)
    Index := Random(Length(Values));

    // Zahl aus Quellenarray lesen
    Result[i] := Values[Index];

    // Letzen Eintrag des Quellenarrays in Values[Index] sichern, danach letzten löschen
    Values[Index] := Values[High(Values)];
    SetLength(Values, Length(Values)-1);
  end;
end;


klabri - Mo 03.11.08 23:40

Hallo,
ich komm erst jetzt dazu zu antworten;
erst einmal DANKE fuer alle Tipps!!

Ich hab hier so eine Lösung,die eigentlich
zu simpel ist ...

i,j,k,z,x:integer;
a:array[1..100]of integer;


begin
ListBox1.Clear;
randomize;
for i:=1 to 20 do
begin
x:=x+1;
j:=i;
z:=random(15)+1;
a[i]:=z;

if i>1 then
for k:=j-1 downto 1 do
begin
if a[k]=a[i] then a[i]:=0;
end;
if a[i]> 0 then ListBox1.Items.Add(IntToStr(a[i]));


end;
end;


oldmax - Di 04.11.08 10:29

Hi
Auf diese Lösung bist du aber nicht etwa stolz ? Sicherlich hast du schon ein paar Beiträge in diesem Forum gelesen und ist es nicht auch schön übersichtlich, wenn der Code dann so schön formatiert ist? Hast du die Antworten überhaupt gelesen und wenn, warum befolgst du nicht den ein oder anderen Hinweis?

Zitat:
Bitte benutze für Delphi-Codes in Zukunft die Delphi-Tags ().


Du solltest aus den Antworten auch ein wenig lernen, sonst ist unsere Arbeit umsonst....
Gruß oldmax


klabri - Fr 07.11.08 17:47

Hallo
und wie mach ich das mit den Delphi-Tags...?


Delete - Fr 07.11.08 17:54

Schreiber dein Code einfach in (Delphi) und (/delphi).Ersetze die runden , durch
eckige KLammern!


Delete - Fr 07.11.08 17:54

[delphi]Quellcode[/delphi]


klabri - Fr 07.11.08 19:26

Hallo,
also die Lösung von GT-Place ist das,was ich wollte.
Hab den Ablauf verstanden und auch wo die Fehler
waren. Frage ist also beantwortet. Danke !!
Mit der anderen Lösung TStringList usw. muss ich mich
erst noch auseinandersetzung,reicht mein Wissen noch
nicht so ganz aus ..Danke auch fuer den Hinweis mit
den Delphi-Tags; weiss jetzt wie`s geht




Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
var 
i,z,k:integer ; 
found:Boolean; 
a:array[1..20]of integer ; 
for i := 1 to 20 do  
begin   
  found := false ;  //keine Zahl 

  while found=false  do
  begin
    
    z := Random(30) + 1;
found:=True;  //Zahl gezogen 
    for k := i downto 1 do  //Zahl schon da ?
      if a[k] = z then      //wenn ja wiederhole
        found := false;
  end;

  a[i] := z;         //Zahl ins  Array; 
end;


Okay, danke !!