Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - random(100) außer bestimmte Zahlen


Perfektionist - Fr 17.09.10 19:25
Titel: random(100) außer bestimmte Zahlen
Hallo zusammen, (Hoffe ich bin hier in der richtigen Kategorie)
es geht um folgendes. Ich will ein Programm schreiben, bei dem a[0] bis a[29] eine zufällige Zahl zugewiesen wird. die werden dann später in immer jeweils einem einem label dann angezeigt. WICHTIG ist, dass keine Zahl doppelt vorkommt. hab nun folgendes programmiert und wenn ich das programm starte, hängt sich das programm beim buttonclick auf.

hier mal mein code:




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:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Label0: TLabel;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    Label7: TLabel;
    Label8: TLabel;
    Label9: TLabel;
    Label10: TLabel;
    Label11: TLabel;
    Label12: TLabel;
    Label13: TLabel;
    Label14: TLabel;
    Label15: TLabel;
    Label16: TLabel;
    Label17: TLabel;
    Label18: TLabel;
    Label19: TLabel;
    Label20: TLabel;
    Label21: TLabel;
    Label22: TLabel;
    Label23: TLabel;
    Label24: TLabel;
    Label25: TLabel;
    Label26: TLabel;
    Label27: TLabel;
    Label28: TLabel;
    Label29: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  a,c,d,z,f,y,g:integer;
  e:boolean;
  b:array[0..29of integer;

implementation

{$R *.dfm}


procedure TForm1.Button1Click(Sender: TObject);
begin
a:=random(100);

c:= 29;
while  c>=0 do
   begin
   g:= random(100);
   f:=0;
   d:=29;
      while d>=0 do
      begin
      if g<>b[d] then
      f:=f+1;
      if g<>b[d] then
      d:=d-1;
      if g=b[d] then
      d:=d-1;
      end;
   if f=29 then
   c:=c-1;
   if f=29 then
   b[c]:=g;
end;
Label0.Caption := IntToStr(b[0]);
Label1.Caption := IntToStr(b[1]);
Label2.Caption := IntToStr(b[2]);
Label3.Caption := IntToStr(b[3]);
Label4.Caption := IntToStr(b[4]);
Label5.Caption := IntToStr(b[5]);
Label6.Caption := IntToStr(b[6]);
Label7.Caption := IntToStr(b[7]);
Label8.Caption := IntToStr(b[8]);
Label9.Caption := IntToStr(b[9]);
Label10.Caption := IntToStr(b[10]);
Label11.Caption := IntToStr(b[11]);
Label12.Caption := IntToStr(b[12]);
Label13.Caption := IntToStr(b[13]);
Label14.Caption := IntToStr(b[14]);
Label15.Caption := IntToStr(b[15]);
Label16.Caption := IntToStr(b[16]);
Label17.Caption := IntToStr(b[17]);
Label18.Caption := IntToStr(b[18]);
Label19.Caption := IntToStr(b[19]);
Label20.Caption := IntToStr(b[20]);
Label21.Caption := IntToStr(b[21]);
Label22.Caption := IntToStr(b[22]);
Label23.Caption := IntToStr(b[23]);
Label24.Caption := IntToStr(b[24]);
Label25.Caption := IntToStr(b[25]);
Label26.Caption := IntToStr(b[26]);
Label27.Caption := IntToStr(b[27]);
Label28.Caption := IntToStr(b[28]);
Label29.Caption := IntToStr(b[29]);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
randomize;
y:= 29;
while  y>=0 do begin
b[y]:=-1;
y:=y-1;
end;
Label0.Caption := IntToStr(b[0]);
Label1.Caption := IntToStr(b[1]);
Label2.Caption := IntToStr(b[2]);
Label3.Caption := IntToStr(b[3]);
Label4.Caption := IntToStr(b[4]);
Label5.Caption := IntToStr(b[5]);
Label6.Caption := IntToStr(b[6]);
Label7.Caption := IntToStr(b[7]);
Label8.Caption := IntToStr(b[8]);
Label9.Caption := IntToStr(b[9]);
Label10.Caption := IntToStr(b[10]);
Label11.Caption := IntToStr(b[11]);
Label12.Caption := IntToStr(b[12]);
Label13.Caption := IntToStr(b[13]);
Label14.Caption := IntToStr(b[14]);
Label15.Caption := IntToStr(b[15]);
Label16.Caption := IntToStr(b[16]);
Label17.Caption := IntToStr(b[17]);
Label18.Caption := IntToStr(b[18]);
Label19.Caption := IntToStr(b[19]);
Label20.Caption := IntToStr(b[20]);
Label21.Caption := IntToStr(b[21]);
Label22.Caption := IntToStr(b[22]);
Label23.Caption := IntToStr(b[23]);
Label24.Caption := IntToStr(b[24]);
Label25.Caption := IntToStr(b[25]);
Label26.Caption := IntToStr(b[26]);
Label27.Caption := IntToStr(b[27]);
Label28.Caption := IntToStr(b[28]);
Label29.Caption := IntToStr(b[29]);
end;
end.


Hoffe ihr könnt mir helfen und Danke schonmal im voraus.

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


Gausi - Fr 17.09.10 19:43

Wenn man x unterschiedliche Zahlen aus dem Bereich 1 bis y haben will, dann macht man das am besten so:

1.) Schreibe die Zahlen 1 bis y in ein Array der passenden Größe.
2.) Mische dieses Array mit Fisher-Yates [http://www.delphi-library.de/viewtopic.php?t=71713].
3.) Wähle aus dem gemischten Array die ersten x Elemente.

Warum sich dein Programm aufhängt: Keine Ahnung - ich blicke durch die Schleifenkonstruktion nicht ganz durch, vermutlich ist das einfach eine Endlosschleife. ;-)

Edit: Ups, Vergessen: :welcome: in der Entwickler-Ecke! :D


Tilman - Fr 17.09.10 20:07

Genau. Du schreibst einfach die Zahlen 0-99 in ein enstprechendes Array. Das brauchst du noch nichtmal zu mischen: du schreibst einfach immer, wenn du eine Zahl aus dem Array herausholst, -1 an die Stelle, und prüfst dann (mit einer while oder repeat...until Schleife) bei jeder Zufallszahl ob sie ungleich -1 ist.


Perfektionist - Fr 17.09.10 20:07

Danke.
Leider verstehe ich aber noch nicht so ganz wie das FisherYates Prinzip funktioniert. werde mir die zeit jetzt erstmal nehmen und das bespielt mit den lotttoziehungen anschauen.

vllt findet ja noch jmd. den fehler bei meinem programm. denn ich denke ttheoretisch müsste das klappen.

---Moderiert von user profile iconNarses: Beiträge zusammengefasst---

user profile iconTilman hat folgendes geschrieben Zum zitierten Posting springen:
Genau. Du schreibst einfach die Zahlen 0-99 in ein enstprechendes Array. .

was heißt in ein array schreiben? ist das das: b:array[0..29] of integer;?


Tilman - Fr 17.09.10 20:15

Ja genau. Nennen wir das Array z.B. "Zufallszahlen". Dann musst du

Delphi-Quelltext
1:
2:
zufallszahlen[0] := 0;
zufallszahlen[1] := 1;


und so weiter schreiben, am besten in einer Schleife natürlich, um die Hand zu schonen ;)

//edit äh doch nicht ganz: wie Gausi schon sagte, das Array muss das gesamte Spektrum der Zufallszahlen umfassen, in deinem Fall, random(100), sind das die Zahlen 0-99.

Und später weißt du dann deinem array "b" diese Zahlen zu, also z.B. b[15] := zufallszahlen[random(100)], wobei du aber wie gesagt erst prüfen musst ob Zufallszahlen[random[100)] ungleich -1 ist. Und wenn es erfolgreich war, dann musst du da -1 reinschreiben, damit du die Zahl nicht noch einmal verwendest.


Gausi - Fr 17.09.10 20:23

@user profile iconTilman: Das mit der -1 sollte man lieber nicht machen. Lies dir dazu die Anmerkungen von user profile iconNarses in dem Topic durch. ;-)


Tilman - Fr 17.09.10 20:31

Da hat Narses ja auch völlig recht ;) allerdings handelt es sich hier wohl um eine Schüleraufgabe, bei der es nicht so sehr darum geht wie zufällig nun der Zufall im einzelnen ist ;) Aber hast schon recht.


Perfektionist - Fr 17.09.10 21:04

user profile iconTilman hat folgendes geschrieben Zum zitierten Posting springen:
Ja genau. Nennen wir das Array z.B. "Zufallszahlen". Dann musst du

Delphi-Quelltext
1:
2:
zufallszahlen[0] := 0;
zufallszahlen[1] := 1;


und so weiter schreiben, am besten in einer Schleife natürlich, um die Hand zu schonen ;)

//edit äh doch nicht ganz: wie Gausi schon sagte, das Array muss das gesamte Spektrum der Zufallszahlen umfassen, in deinem Fall, random(100), sind das die Zahlen 0-99.

Und später weißt du dann deinem array "b" diese Zahlen zu, also z.B. b[15] := zufallszahlen[random(100)], wobei du aber wie gesagt erst prüfen musst ob Zufallszahlen[random[100)] ungleich -1 ist. Und wenn es erfolgreich war, dann musst du da -1 reinschreiben, damit du die Zahl nicht noch einmal verwendest.


SUPER VIELEN DANK. habs hinbekommen :)


Mr_Emre_D - Fr 17.09.10 23:16


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:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
function RandomExt(const Range: Integer; const ExceptionalValues: Array of Integer): Integer;
var
  i, j, k : Integer;
  dwRange : DWord;
  Sign    : ShortInt;
  Values  : Array of Integer;
  function IsExceptionalValue(const V: Integer): Boolean;
  var
    i: Integer;
  begin
    Result := False;
    for i := 0 to High(ExceptionalValues) do
      if V = ExceptionalValues[i] then
      begin
        Result := True;
        break;
      end;
  end;
begin
  Result := 0;
  if Range > 0 then
    Sign := 1
  else
  if Range < 0 then
    Sign := -1
  else
    Exit;
  dwRange := Abs(Range);
  SetLength( Values, dwRange );
  j := 0;
  for i := 0 to dwRange - 1 do
  begin
    k := Sign * i;
    if not IsExceptionalValue(k) then
    begin
      Values[j] := k;
      inc( j );
    end;
  end;
  if j > 0 then
    Result := Values[Random(j)];
end;



Delphi-Quelltext
1:
2:
3:
(* Aufruf *)
  ShowMessage( IntToStr( RandomExt( 5, [0,1,2] ) ) );
(* (Mathematisch) Result Element aus {0..Range-1} \ {ExceptionalValues} *)


MfG


Kha - Fr 17.09.10 23:46

Bei einer zufälligen Permutation hilft das aber wenig weiter. Ein ziemlich optimaler Algorithmus wurde ja schon genannt und der Thread ist anscheinend erledigt :nixweiss: .