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
Tino: 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:
- mache aus random(49)+1 lieber random( 48 )+1
- 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
DeCodeGuru: 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
DeCodeGuru: Code- durch Delphi-Tags ersetzt
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!