Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - 7 Variablen miteinander Vergleichen


Delete - Do 06.02.03 15:55
Titel: 7 Variablen miteinander Vergleichen
Hey,
wir sollen für Info ein Lottozahlen Prog. programmieren.
Dazu dürfen die Variablen, die ich im Array erstellt habe ja nicht gleich sein.
Unser Lehrer meinte, dass wir versuchen sollen nicht alle Variablen mit einander einzeln zu Vergleichen sondern mit for-Schleifen.
Ich habe ein paar Variationen ausgetestet, aber es klappt nix. Wisst ihr, wie es gehe könnte??

cu

nGerrit


Chris1308 - Do 06.02.03 16:09

Hm... ich will dir jetzt nicht die Hausaufgaben machen (obwohl es mich reizen würde ;) ), aber dazu kann ich dir 2 Tipps geben:
1. Schau dir in der Hilfe mal For-Schleifen an
2. Du brauchst 2 (für jedes Array 1)...

Chris

PS: Ich würde dir das Programm ja vollständig geben, aber dann wäre es meine Hausaufgabe...


Delete - Do 06.02.03 18:36

Hmm..
das mit den 2 Arrays war mit klar. Ich habs nur nicht zum laufen bekommen...
Ich bekomm immer ne endlos Schleife raus, obwohl es eigentlich funktionieren müsste ;)

Vielleicht könnt ihr mir ja sagen, wo der Fehler ist..

nGerrit

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:
procedure TForm1.Button1Click(Sender: TObject);
var index:integer;
var index2:integer;
begin
Randomize;
for
  index := 1 To 7
Do
  Begin
  Lottozahlen[index] := Random(49)+1;
  end;

for
  index := 1 To 7
Do
  Begin
    for
      index2 := 1 To 7
    Do
      Begin
        while
          lottozahlen[index] = lottozahlen[index2]
        Do
          lottozahlen[index2] := Random(49)+ 1
      end;
  end;


Moderiert von user profile iconTino: Code-Tags hinzugefügt.


Chris1308 - Do 06.02.03 18:53

In folgender Zeile:

Quelltext
1:
2:
while lottozahlen[index] = lottozahlen[index2] do 
lottozahlen[index2] := Random(49)+ 1

Ich "übersetze" mal:

Quelltext
1:
2:
wiederhole folgendes solange, bis lottozahl[i] gleich lottozahl[i2] ist:
lottozahlen[i2] := random(49)+1

Folgendes solltest du machen:

  1. mache aus random(49)+1 lieber random( 48 )+1
  2. schreibe die While-Schleife lieber so um:

    Quelltext
    1:
    while lottozahlen[index] <> lottozahlen[index2] do {...}                    



Chris


Delete - Do 06.02.03 19:32

Hmm
ein Fehler hab ich erstmal gefunden

lottozahlen[index] = lottozahlen[index2]

Ist immer gleich, weil beim erstendurchlauf index und index2 1 ist...

Wieso soll ich aus den random 49 48 machen? lottozahlen haben 49...

Wenn ich die while schleife so änder, wie du willst, macht er keine neue Zahlen..




nGerrit


Chris1308 - Do 06.02.03 19:50

Ooops.. habe gerade selber einen Fehler gesehen. Also, 48, weil du ja +1 nimmst und 49+1 50 ist und 50 für gewöhnlich nicht in den Lottozahlen auftaucht. Ich habe deinen Source nochmal ein wenig verändert. Kommentare enthalten:


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
procedure TForm1.Button1Click(Sender: TObject); 
var i:integer; 
      i2:integer;     // du brauchst nur 1x var
begin 
{ Randomize; } // würde ich in's OnCreate-Ereignis schreiben (doppelklick auf Formular)
for i := 1 to 7 do begin 
  Lottozahlen[i] := Random(48)+1;  // siehe oben
end; 

for i := 1 to 7 do begin 
  for i2 := 1 to 7 do begin
    repeat // wiederhole folgendes solange, bis..
      lottozahlen[i2] := random(48) + 1;  // s.o.
    until lottozahlen[i] <> lottozahlen[i2]; // ...das hier stimmt
  end; 
end;


So, ich hoffe Source erklärt sich von selbst.
Kleine Begründung, warum es mich gereizt hätte, deine Hausaufgaben zu machen: ich selber habe noch kein Informatikunterricht und ich schreibe meine Programme immer nur als Hobby. Da reizt es mich schon mal einfache Sachen für jemanden zu machen (also z.B. Lehrer (auch wenn ich nicht gerade ein Freund von Pädagogen bin)).

Chris

PS: Achja, Source wie meistens ungetestet...


Delete - Do 06.02.03 20:07

hmm mit dem random haben wir gelernt, dass man immer ein mehr als man will angeben muss, weil der den bereich festlegt und das nicht inclusive ist, oder so.. ist ja auch erstmal nicht mein hauptproblem...

Ich sag zum Quellcode:
Nach wie vor Endlosschleife *G*

nGerrit


Chris1308 - Do 06.02.03 20:11

Das ist aber ein Problem von der random-Funktion!
Ich bin sowieso dafür, dass Borland eine neue Funktion schreibt... :x

Chris


iaby - Do 06.02.03 21:43

genau:
die aufruf random(49) liefert dir zufällige zahlen von 0 angefangen. insgesamt kann er dann 49 verschiedene zurückgeben-> also bei 0 angefangen, kommt man nur bis 48!
+1 stimmt also schon!


Delete - Do 06.02.03 21:44

Wieso? Random liefert Zufallszahlen von 0 bis Grenze. Und die Lottozahlen gehen von 1 bis 49, zu mindest hier in Deutschland. Und da man verhindern muß das 0 rauskommt, muß man generell eins dazu addieren.


Delete - Do 06.02.03 22:20

Um den Kack geht es mir doch gar nicht *G* (soory)
Mein Programm läuft nicht. Hat nicht einer dazu noch ne idee?

nGerrit


smiegel - Do 06.02.03 22:34

Hallo,

versuche einmal folgendes:


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:
type
  TLottozahlenArr=array[1..7] of Integer;

function ZieheZahlen:TLottozahlenArr;
var i, j:Integer;
     ok :Bool;
begin
  FillChar(Result, SizeOf(TLottoZahlenArr), 0);
  i:=1;
  repeat
    Result[i]:=Random(48)+1;
    ok:=True;
    if (i>1) then 
    begin
      for j:=1 to i-1 do if (Result[i]=Result[j]) then
      begin
        ok:=False;
        Break;
      end; // if, for
    end; // if
    if ok then Inc(i);
  until (i>7);
end; // ZieheZahlen


var
  Ziehung:TLottozahlenArr;

  ...
  Ziehung:=ZieheZahlen;
  ...


Steve_B - Sa 08.02.03 13:10

Um nochmal auf den "Ursprungs-Code" zurückzukommen:
Die while-Schleife ist eine Endlosschleife. Schon beim ersten Durchlauf der beiden for-Schleifen ist index=index2, also wird die Zahl immer wieder mit sich selbst verglichen. Baue in die Schleifenbedingung eine and-Verknüpfung ein, so daß die while-Schleife nur ausgeführt wird, wenn index ungleich index 2 ist:

Quelltext
1:
while (index<>index2) and (Lottozahlen[index]=Lottozahlen[index2]) do ...                    

Ansonsten sollte es laufen, wie es da ist.
Allerdings ist es dann immer noch möglich, daß am Ende 2 gleiche Zahlen vorhanden sind. z.B.:
Lottozahlen[1]=1; Lottozahlen[2]=2; Lottozahlen[3]=2; ...
Das erkennt das Programm und ändert es, dabei könnte folgendes rauskommen:
Lottozahlen[1]=1; Lottozahlen[2]=2; Lottozahlen[3]=1; ...
Auch das wird nochmal erkannt und geändert, dann könnte es so aussehen;
Lottozahlen[1]=2; Lottozahlen[2]:=2; Lottozahlen[3]:=1 ...
Dann erkennt das Programm aber nicht mehr, daß eine Zahl (in diesem Beispiel die 2) mehrmals vorkommt.
Die Wahrscheinlichkeit ist da aber sehr gering...


Delete - Sa 08.02.03 13:33

Hmm. Danke, aber warscheinlichkeit gering ist sche**** *G*

Wenn ich das vorführen muss und dat nicht klappt ist das auch nicht so schön..
Ich denke, ich muss was amchen, dass wenn er was verändert alle nochmal ztu prüfen *g*

Ich melde mich, wenn ich was raus hab

cu
nGerrit


waldmeister - Sa 08.02.03 14:14

ich würde die zahlen anders ziehen!
als erstes ein array [0..48] erstellen un dann mit ner for-schleife die zahlen von 1-49 eintragen:


Quelltext
1:
2:
3:
4:
5:
6:
var
zahlen: array [0..49] of integer;
i,zahl1, zahl2, tausch: integer;
begin
for i:=1 to 49 do
zahlen[i-1]:=i;


dann würd ich die zahlen alle miteinander tauschen:


Quelltext
1:
2:
3:
4:
5:
6:
7:
for i:=1 to 10000 do begin
zahl1:=Random(49)+1;
zahl2:=Random(49)+1;
tausch:=zahl1;
zahl1:=zahl2;
zahl2:=tausch;
end;


un jetzt kannste die ersten 7 werte vom array nehmen un als deine lottozahlen nehmen!

als kompletter text säh dass dann so aus:


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
Procedure lottozahlen;
var
  zahlen: array [0..49] of integer;
  i,zahl1, zahl2, tausch: integer; 
begin
  for i:=1 to 49 do 
    zahlen[i-1]:=i;
  for i:=1 to 10000 do begin
    zahl1:=Random(49)+1;
    zahl2:=Random(49)+1;
    tausch:=zahl1;
    zahl1:=zahl2;
    zahl2:=tausch;
    end;
end;


am ende würd ich unter noch folgendes eintragen:

Quelltext
1:
2:
3:
4:
end;
initialization
randomize;
end.


Steve_B - Sa 08.02.03 14:50

Man kann auch einfach die beiden for-Schleifen in eine repeat-Schleife "packen", die solange wiederholt wird, bis keine Zahl öfter als ein mal vorkommt. Hört sich vielleicht ein wenig kompliziert an, ist aber ganz einfach:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
procedure TForm1.Button1Click(Sender: TObject);
var index,index2:Integer;
    ungleich:Boolean;
begin
for index:=1 to 7 do
Lottozahlen[index]:=Random(49)+1;
repeat
    ungleich:=true;
    for index:=1 to 7 do
    for index2:=1 to 7 do
    if (index<>index2) and (Lottozahlen[index]=Lottozahlen[index2]) then begin
        Lottozahlen[index2]:=Random(49)+1;
        ungleich:=false;
        Break;
    end;
until ungleich;
end;

Dann dürfte es keine (auch noch so kleine) Möglichkeit mehr geben, daß eine Zahl öfter als ein mal vorkommt.


Delete - Sa 08.02.03 19:58

Mensch Jungs ihr seid Genial. Ich teste mal eben aus, ob dat funktioniert und dann schreib ich noch was dazu DANKEEEE! *G*

nGerrit


Delete - Sa 08.02.03 20:06

waldmeister hat folgendes geschrieben:

dann würd ich die zahlen alle miteinander tauschen:


Quelltext
1:
2:
3:
4:
5:
6:
7:
for i:=1 to 10000 do begin
zahl1:=Random(49)+1;
zahl2:=Random(49)+1;
tausch:=zahl1;
zahl1:=zahl2;
zahl2:=tausch;
end;


hmm. Den Teil deines Quelltextes versteh ich noch nicht ganz. Du führst eine schleife 10000 mal aus, in der das gleiche Passiert.. Verändert sich doch nix, dadurch, dass du den so oft ausführst! Du hast 2 Zahlen, denen Randomwerte zugewiesen werden. Benutzten tust du die beiden Zahlen auch nicht mehr.. Erklär mal bitte!

nGerrit


waldmeister - So 09.02.03 13:19

das is ganz einfach. zahl1 und zahl2 sind ein Index von deinem Array in dem die 49 Lottozahlen stehen. Die werden zufällig ermittelt (Random) und dann getauscht. Wenn du das 1000 mal machst, dann hast du alle 49 zahlen gut gemischt und kannst die ersten 7 zahlen nehmen weil dass dann genauso ist als hättest du zufällig 7 aus den 49 raus gezogen und dann mühsam miteinander verglichen obs nicht die selben sind!


Wolff68 - So 09.02.03 21:17

Deine Idee, alle Zahlen nochmalzu prüfen wenn sich was geändert hat ist schon richtig.

Hier mal ein Beispiel:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
procedure TForm1.Button1Click(Sender: TObject);
var
  i, j : integer;
  changed : boolean;
begin
  Randomize;

  For i := 1 to 7
    do Zahlen[i] := Trunc(Random(49)+1);

  Repeat
  changed := false;
    For i := 1 to 7 do begin // Alle Zahlen durchgehen
      For j := i+1 to 7 do begin // Alle folgenden Zahlen vergleichen
        IF Zahlen[i] = Zahlen[j] then begin // Wenn gleich letzte neu
          Zahlen[j] := Trunc(Random(49)+1);
          changed := true; // Und merken, daß sich was geändert hat
        end;
      end;
    end;
  until changed = false;
end;


@Chris1308:
1. Bedeutet While übersetzt nicht 'wiederhole ... solange' (das wäre Repeat until) sondern 'solange... mache...'
2. Wollen wir Doppelte vermeiden, nicht erzeugen! Also ist auch das Lotto[index] <> Lotto[index2] genau entgegen dem was hier beabsichtigt ist.
3. Steht in der Delhpi-Hilfe folgendes zu Random: Bereich 0 <= X < Range Also gibt Random (49) Zahlen zwischen 0.0000001 und 48.999999 abern NIE 49. Wenn man also mit Trunc Integer bildet immer zwischen 0 und 48 ! Daher ist das +1 schon richtig. (Mit Round wäre übrigends die Wahrscheinlichkeit für 49 geringer als für alle anderen)

Gruß, Wolff


Wolff68 - So 09.02.03 21:33

Chris1308 hat folgendes geschrieben:
Das ist aber ein Problem von der random-Funktion!
Ich bin sowieso dafür, dass Borland eine neue Funktion schreibt...
Und ich wäre dafür, daß Du erstmal beginnst mit dem Vorhandenen richtig umzugehen. Borland hat sich da schon seine Gedanken gemacht.

@Waldmeister: *Lach* Der Lehrer würde sicher staunen. Funktioniert zwar, aber ist GARANTIERT nicht das was er sehen will. (Sofern er es versteht)
Ist zwar cool. Aber ziemlich mit Kanonen auf Spatzen geschossen, oder ?

Dabei geh ich mal davon aus, daß Du Zahlen[Zahl1] und Zahlen[Zahl2] gemeint hast. Also hier mal richtiger:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
for i:=1 to 10000 do begin 
  zahl1:=Random(49)+1
  zahl2:=Random(49)+1
  tausch:=Zahlen[zahl1]; 
  Zahlen[zahl1] := Zahlen[zahl2]; 
  Zahlen[zahl2] := tausch; 
end;


Moderiert von user profile iconDeCodeGuru: Code- durch Delphi-Tags ersetzt


Brueggendiek - Mo 10.02.03 01:03

Hallo Leute!

Da soll ein Programm zur Lottoziehung geschrieben werden und man bricht sich die Finger bei der Random-Auswahl.

Kleiner Tip: baut euch doch die Ziehungsmaschine und legt los!

Realisierung: Eine Stringlist nehmen, die Zahlen von 1 bis 49 zeilenweise als String eintragen.
Dann mit Random(liste.Count) eine Kugel auswählen, den Wert in das Array schreiben und die Kugel (Zeile) aus der Stringlist entfernen.

Dadurch gibt es jede Zahl garantiert nur einmal und man muß nicht suchen, ob die Zahl schon gezogen wurde.
Obendrein wäre hiermit ein Sytem möglich, wo z.B. jedes Element mehrfach vorkommt (z.B. Black Jack, Schwarzer Peter) oder nichtnumerische Werte gezogen werden (alle Kartenspiele)
Diese Methode ist besonders geeignet, wenn man alle Zahlen von a bis b in zufälliger Reihenfolge benötigt.

Alternative: Zahl ziehen, mit allen schon gezogenen Zahlen vergleichen, bis nicht gefunden. Nachteil hier: bei vielen Zahlen (andere Anwendungen mit z.B. 5 aus 6) dauert es am Ende sehr lange, bis der Zufall eine der verbleibenden Zahlen trifft.

Fazit: Bei kleiner Zahl gezogener Werte (wie Lotto) kann man jede Zahl ziehen und prüfen, ob sie gültig ist. Bei vielen Zahlen sollte auf jede Fall die Stringlist her - benötigt pro gezogenem Wert nur 1 Random.

Gruß

Dietmar Brüggendiek


waldmeister - Di 11.02.03 18:47

zugegeben, mein system is vielleicht nicht das einfachsteste für dieses problem aber sicherlich doch effektiv und es funktioniert auf jeden fall!


Delete - Di 24.02.04 21:00

hi also ich hab hier gerade nochmal drin rumgesucht, weil n freund n ähnliches problem hat. und ich hab dann später meinen alten funktionierenden code gefunden.. dachte ich poste den einfach mal fröhlich hier rein :)

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
for
  index:=1 to 7
do
  Lottozahlen[index]:=Random(49)+1;
repeat
  ungleich:=true;
  for
    index:=1 to 7
  do
    for
      index2:=1 to 7
        do
          if
           (index<>index2) and (Lottozahlen[index]=Lottozahlen[index2])
          then
            begin
              Lottozahlen[index2]:=Random(49)+1;
              ungleich:=false;
            end;
until ungleich=true;

have fun

nGerrit @2004

Moderiert von user profile iconDeCodeGuru: Code- durch Delphi-Tags ersetzt