[Pascal]Zahlen in Array schreiben!

TobGod

Erfahrenes Mitglied
Hi, ich habe folgendes Problem:
Code:
FOR Lauf := 1 TO 7 DO
  BEGIN
    Randomize;
    Zahl         := Random(49);
    Zahl         := Zahl+1;
    Zahlen[Lauf] := Zahl;
  END;

Es sollen einfach nur in das Array sieben Zufallszahlen eingelesen werden. Lasse ich das Array[1..7] hinterher wieder ausgeben, steht überall die selbe Zahl drin, also Zahlen[1] = Zahlen[2] = Zahlen[3] usw. Wie kriege ich das hin ?

Ok das Problem habe ich behoben, das Randomize musste über die FOR-Schleife, warum auch immer. Nun möchte ich aber noch, dass in dem Array jede Zahl nur einmal vorkommt. Wie schaff ich das ?
 
Zuletzt bearbeitet:
Stell dir den Befehl randomize mal als Zufallszahlengenerator vor, der immer eine bestimmte Reihenfolge einhält. Startest du ihn immer neu, und liest direkt danach die Zahl aus, ist die logischerweise immer gleich. Das erklärt dein anfängliches Problem.

Und zu dem noch bestehenden: sei doch mal kreativ ;) Du könntest die Zahlen in einem Set speichern, und dadurch prüfen, du könntest mit einer repeat-until-Schleife und einer anderen Zählschleife solange neue Zahlen ziehen, bis die gezogene Zahl nicht in den anderen Feldern gefunden wird...

Ich persönliche würde dir das Set empfehlen, besonders bei größeren Arrays geht das imho schneller. Falls du noch Fragen hast, helfen wir dir sicher gern weiter.

PS: Wie wärs denn damit:
Code:
Randomize;
FOR Lauf := 1 TO 7 DO
    Zahlen[Lauf] := Random(49)+1;

lg Hellie
 
Danke erstmal für deine Antwort. Ich weiß leider nicht was ein "Set" ist, da wir noch nicht lange Pascal in der Schule haben. Wir lernen es erst und dieses Programm sollen wir als Hausaufgabe machen. Also ich habe es jetzt mit repeat-until gemacht, wobei das wirklich sehr sehr aufwendig ist:
Code:
UNTIL(Zahlen[1]<>Zahlen[2]) and
         (Zahlen[1]<>Zahlen[3]) and
         (Zahlen[1]<>Zahlen[4]) and
         (Zahlen[1]<>Zahlen[5]) and
         (Zahlen[1]<>Zahlen[6]) and
         (Zahlen[1]<>Zahlen[7]) and
         (Zahlen[2]<>Zahlen[3]) and
         (Zahlen[2]<>Zahlen[4]) and
         (Zahlen[2]<>Zahlen[5]) and
         (Zahlen[2]<>Zahlen[6]) and
         (Zahlen[2]<>Zahlen[7]) and
         (Zahlen[3]<>Zahlen[4]) and
         (Zahlen[3]<>Zahlen[5]) and
         (Zahlen[3]<>Zahlen[6]) and
         (Zahlen[1]<>Zahlen[7]) and
         (Zahlen[4]<>Zahlen[5]) and
         (Zahlen[4]<>Zahlen[6]) and
         (Zahlen[4]<>Zahlen[7]) and
         (Zahlen[5]<>Zahlen[6]) and
         (Zahlen[5]<>Zahlen[7]) and
         (Zahlen[6]<>Zahlen[7]);
 
Untersuche doch einfach die Zahl, die du gerade gezogen hast, mit allen vorher. Das kannst du einfach mit einer Zählschleife (for i:=1 to lauf-1) überprüfen, also mit einer Selektion auswählen und in einem Boolean-Wert speichern, und den dann am Ende im until-Teil überprüfen. Wenn dabei herauskommt, dass die Zahl noch nicht gezogen wurde, kannst du sie setzen und deine Zählvariable Lauf eins höher setzen lassen (macht es ja automatisch).
So wie du es schon machst, ist es auch okay, aber stell dir mal vor, du solltest 100 Zahlen ziehen ;).

Wenn du Fragen hast, helfen wir dir auch weiter gerne, keine Frage. Wenn du Interesse hast, kannst du auch noch lernen, was ein Set ist. Komisch, wir haben es zusammen mit Arrays kennengelernt.

lg Hellie

PS: Gibt es eigentlich irgendjemanden, der in der Schule programmieren gelernt hat und nie ein Lotto-Programm coden sollte? :)
 
Hm sorry aber ich komm da nicht hinter was du meinst mit der FOR-Schleife. Wie soll ich das überprüfen ? Also ich bin totaler Anfänger, sorry.
also mit einer Selektion auswählen und in einem Boolean-Wert speichern, und den dann am Ende im until-Teil überprüfen
Selektion und Boolean-Wert sagt mir garnichts und das dann am Ende mit until prüfen. Hm, das bräuchte ich alles ein bisschen genauer, wenns geht :confused: . Trotzdem vielen Dank schonmal für deine Antworten bis jetzt.
 
Also...

eine Selektion ist eine Auswahl. Vielleicht habt ihr das nur nie unter dem Namen gehabt. man unterscheidet einseitige, zweiseitige und mehrseitige Auswahl:
einseitig: if Bedingung then Anweisung
zweiseitig: if Bedingung then Anweisung1 else Anweisung2
Mehrseitig: case Variable of Vergleich1: Anweisung1; Vergleich2: Anweisung2;... end;

Du brauchst also die erste.

Ein Boolean-Wert ist ein bestimmter Variablentyp, der nur true oder false sein kann. Die Deklaration ist auch dementsprechend:
Code:
var x:boolean;

Um dir ein wenig auf die Sprünge zu helfen, hier mal der - von mir heißgeliebte - Grobalgorithmus: :)
Code:
von lauf:=1 bis 7 tue  //für jede Zahl, die gezogen wird  
   wiederhole
      frei:= true //Zahl im Feld noch nicht gefunden
      zahl:= random(49+1) //Zahl, die man einsetzen will, "erwürfeln"
      von i:=1 bis lauf-1 tue //für alle Zahlen, die schon gezogen wurden
         falls ((Zahlen[i]= Zahl) und (frei) dann frei:=false //merke, wenn Zahl schon vorhanden
   bis frei //solange weitermachen, bis Zahl gefunden, die nicht im Feld vorhanden ist
   zahlen[lauf]:=zahl //Zahl ins Feld übertragen

So, das ist schon fast vollständiger Code, und ich denke, auch ausreichend kommentiert. Das soll aber nicht heißen, dass du ohne nachzudenken, den Code übersetzen sollst. Falls es Fragen gibt, sag bitte Bescheid! geh den Code am besten durch, und merk dir die Stellen, die dir unlogisch erscheinen. Ich versuche dann, es dir zu erklären, wobei ich irgendwie das Gefühl habe, total in den Ferien zu sein und keine vollständigen Sätze mehr bilden zu können.

Ich hoffe, ich kann dir irgendwie helfen.

lg Hellie
 
Ehm, jetzt verstehe ich dich garnicht mehr.
Code:
von lauf:=1 bis 7 tue  //für jede Zahl, die gezogen wird  
   wiederhole
      frei:= true //Zahl im Feld noch nicht gefunden
      zahl:= random(49+1) //Zahl, die man einsetzen will, "erwürfeln"
      von i:=1 bis lauf-1 tue //für alle Zahlen, die schon gezogen wurden
         falls ((Zahlen[i]= Zahl) und (frei) dann frei:=false //merke, wenn Zahl schon vorhanden
   bis frei //solange weitermachen, bis Zahl gefunden, die nicht im Feld vorhanden ist
   zahlen[lauf]:=zahl //Zahl ins Feld übertragen

Sorry, aber da werde ich aus keinem einzigen Satz schlau raus !? Also ich sehe da irgendwie absolut keine Zusammenhänge..und das Deutsche dann noch, da is man ja komplett verwirrt. z.B. lauf-1, Warum ? Ich bin kein Genie oder so, also ich kann mir das nicht beibringen :( Sorry..
 
Okay, sorry, falls ich dich verwirrt habe.

Zum verständnis des Grobalgos: Eigentlich ist es ein Zwischenschritt, der nach der Modellierung (die ich dir davor geboten habe) und vor der Programmierung kommt. Die Programmierung wäre der letzte Schritt erstmal, und der sollte möglichst von dir kommen. Aber in diesem Algorithmus kann man die deutschen Worte durch die jeweilige Struktur der Programmiersprache ersetzen. Der Code ist auch schon angepasst an Pascal.

Die "//" habe ich vorausgesetzt, aber später ist mir aufgefallen, dass du sie evtl. noch nicht kennst: Das sind Kommentarzeichen, alles, was in einer Zeile hinter den zwei direkt aufeinanderfolgenden / steht, wird nicht mit kompiliert. Das hilft, denn dort kann man seine Kommentare loswerden, z.B. den Code noch mal erklären. Ohne Ordnung sieht das ganze auch leicht undurchsichtig aus. Ich versuchs mal durchsichtiger:

Code:
von lauf:=1 bis 7 tue  //für jede Zahl, die gezogen wird   
  wiederhole 
      frei:= true //Zahl im Feld noch nicht gefunden
      zahl:= random(49+1) //Zahl, die man einsetzen will, "erwürfeln"
      von x:=1 bis lauf-1 tue  //für alle Zahlen, die schon gezogen wurden
         falls ((Zahlen[x]= Zahl) und (frei) dann frei:=false  //merke, wenn Zahl schon vorhanden
   bis frei  //solange weitermachen, bis Zahl gefunden, die nicht im Feld vorhanden ist
zahlen[lauf]:=zahl //Zahl ins Feld übertragen

Um es übersichtlicher (?) zu machen, hab ich es mal farbig gemacht... Die Kommentare sind in einem hellen blau gehalten. Die äußere Zählschleife, zu der aber eigentlich alles andere auch gehört, ist dunkelgrün. In Olive ist alles gehalten, dass die Repeat-Until-Schleife an sich darstellt. Darin sollte ja geprüft werden, ob die Zahl schon mal gezogen wurde. Dazu müssen alle zahlen, die schon gezogen wurden, überprüft werden, und zwar durch eine Zählschleife. Die hab ich mal dunkelrot gemacht. Die eigentliche Abfrage ist dann rot, dort wird geprüft.

Dann gibt es noch ein paar Variablen im Grobalgo. Das sind die von dir benutzten (Zahlen, zahl, lauf) sowie eine weitere Zählvariable (umbenannt von i in x, damits nicht kursiv abgebildet wird) und der Boolean-Wert zum Prüfen, den ich "frei" genannt habe, im Sinne von "noch zu vergeben".

Ich hoffe, dir hilft diese Darstellung ein wenig mehr. Durchdenk es dir noch mal, geh den Algorithmus im Kopf vielleicht auch mal durch, das kann auch helfen. Und melde dich bitte auf jeden Fall noch mal, entweder um Fragen zu stellen oder um zu sagen, dass alles verständlich ist. ich werd mich jetzt erstmal von den Tags oben erholen und geh baden...

lg Hellie
 
Hm sorry, das hat sicherlich viel Zeit und Mühe gekostet aber ich verstehe es immernoch nicht. Also ich verstehe nicht warum man da überhaupt irgendwas macht. Das einzigste was ich verstehe ist, dass man die FOR Schleife von 1-7 nimmt weil das Array ja auch von 1-7 groß ist. Weiter komm ich nicht. Ich glaube in Programmieren bin ich echt ein hoffnungsloser Fall. Verstehe das in der Schule schon nie :( Also vielleicht kannst du mir dein Programm einfach mal so erklären, warum du was machst, das wäre wirklich nett. Achja noch was, was ist eigentlich ein Algorhytmus und wofür braucht man die ?
 
Zuletzt bearbeitet:
Ein Algorithmus ist eigentlich nichts weiter als eine Abfolge. Hier eine Abfolge von Befehlen.

Die 1-to-7-Schleife kam ja schon von dir, mit der sollte jedem Feld im Array eine Zahl zugewiesen werden. Du wolltest aber sichergehen, dass keine Zahl doppelt vorkommt, also dass unterschiedliche Zahlen in den Arrayfeldern liegen. Dazu hatte ich dir folgendes geraten:
-erst eine Zahl ziehen
-dann diese Zahl mit den bereits gezogenen vergleichen
-wenn die aktuelle Zahl übereinstimmt mit einer von denen, die du vorher schon "gezogen" hast, noch mal eine neue Zahl ziehen, noch mal vergleichen, und das so lange, bis die immer wieder neu gezogene Zahl nicht mehr zu finden ist (ich hoffe, du erkennst die repeat-until-Schleife darin)
-wurde die gezogene Zahl dann nicht gefunden, kann man sie übertragen in das Array

Die zweite Zählschleife dient einfach nur dazu, die Felder des Arrays zu überprüfen, die schon einen festen Wert zugewiesen bekommen haben. Jedes einzelne Feld wird darin überprüft, ob der Inhalt der gerade gezogenen Zahl entspricht. Wenn ja, wird der Boolean-Wert x auf false gesetzt. Dieser Wert ist dann ausschlaggebend dafür, ob die Schleife, in der eine neue Zahl gezogen und ihr Vorkommen überprüft wird, noch ein mal durchlaufen wird.
Wenn man "frei" nicht wieder auf "true" setzen würde, würde sich im Falle einer doppelt gezogenen Zahl das Programm aufhängen, weil dann nie - aufgrund der fehlenden Anweisung dazu - die Schleife zu Ende wäre, sondern immer wieder neu anfangen würde.

Versuch, dich zurecht zu finden, irgendwie, ich bin jetzt erstmal bis morgen früh nicht da, ich habe über Nacht Besuch :)

lg Hellie
 

Neue Beiträge

Zurück