Zufallszahlen - nicht 2 mal die gleiche ?



  • Hallo!
    Ich muss einen Zufallsgenerator schreiben, bei dem jede Zahl nur 1 mal vorkommen darf. Es dürfen keine Zahlen mehrfach generiert werden. Zusätzlich muss ich einige Zahlen (nicht unbedingt alle auf einmal) auch wieder "freischalten" können, sodass sie wiederum gezogen werden können. Allerdings auch wieder nur 1 mal, bis ich sie erneut freischalte. Ich weiß nicht genau, ob das überhaupt möglich ist, aber ich hoffe ihr könnt mir helfen.



  • Die Zahlen, die nicht "erlaubt" sind, können zum Beilspiel in einem Array gespeichert werden.Das Enzige, was du brauchst, ist ein richtiges Verwalten des Arrays ;).



  • Ich habe mir kurz nachgedacht,dass "set" Container von STL besser dazu geeiget ist.



  • Wenn die Zahlen aus einem sehr großen Wertebereich kommen sollen, könntest du, wie desert pinguin gesagt hat, die bereits gezogenen in einem std::vector (Edit: OK, ein set wäre hier wirklich eine Alternative 😉 ) verwalten. Allerdings wird das Ziehen einer neuen Zahl dann potenziell immer langsamer.

    Wenn du nur einen eher kleinen Wertebereich hast (das std::rand des VC kann z.B. eh nur 2^16 Zahlen ausspucken) und das Ziehen stets schnell gehen soll, würde ich einen std::vector für die noch nicht gezogenen Zahlen nehmen und mit std::random_shuffle (aus <algorithm>) arbeiten. Dann dauert das erste Einrichten länger, aber das Ziehen dafür nicht.



  • Ein Set ordnet die Zahlen aber. Die Frage ist, ob sowas für Zufallszahlen geeignet ist...



  • Also konkret möchte ich eine Karte bestimmen die gezogen wird. Dabei soll es 32 verschiedene Karten geben (Skat-Blatt halt). Ich frage mich ob es vielleicht besser wäre 2 Zufallsgeneratoren zu schreiben, 1 für die Farbe und 1 für das Bild ... dann wären die wertebereiche kleiner (1-4 und 1-8).
    Danke für die Hilfe, allerdings kenne ist set nicht und mit vektoren habe ich bisher kaum gearbeitet (Anfänger 🙄 ) Ein bisschen code wär nicht schlecht oder eine Erklärung wie set arbeitet. THX 😃



  • Dann wäre ich für vector + random_shuffle. Wie du die Karten definierst, musst du dir selbst überlegen 😉 Im Prinzip brauchst du einen "std::vector<DeinKartenTyp> stapel".
    Zum Füllen alle möglichen Karten per push_back() hinzufügen und ihn dann per std::random_shuffle(stapel.begin(), stapel.end()) "mischen".
    Um eine Karte wieder "einzumischen", einfach die Karte nochmal pushen und shufflen.
    Um eine Karte abzunehmen, kannst du die aktuell oberste Karte per vec.back() abfragen und per stapel.pop_back() runternehmen.

    Wenn ihr den Umgang mit der STL noch nicht gelernt habt, sollt ihr das vermutlich anders lösen. So wäre es aber am einfachsten.



  • Wie wäre es damit: Ein Array(irgendeinen Container aus der STL) in denen Zahlen geordnet sind (z.B. von 0 bis 30). Dann wird in einer Schleife 30 mal eine Zufallszahl erzeugt, zuerst zwischen 0 und 30, dann zwischen 0 und 29 usw. Jedesmal wenn eine Zufallszahl erzeugt wird, hat man als ergebnis die Zahl, die im Vektor an diesem Index steht. Dann entfernt man diesen Index aus dem Array (ein Liste wär hier nicht schlecht, oder) und beginnt mit nem neuen Schleifen durchlauf.
    Ich hoffe, ihr habts verstanden. Das würde halt ein bisschen mehr Speicherplatz brauchen, aber geht wahrscheinlich schnell.
    geloescht



  • Nun ja:
    entweder, du hast ein Array -> langsam beim Herausnehmen des Elements
    oder du hast ne Liste -> langsam, um Element mit dem entsprechenden Index zu finden.

    Ich glaub nicht, daß diese Lösung sehr schnell ist...



  • Hm... oh, ja, du hast recht, hab das nicht bedacht bei der Liste mit dem Suchen des Index... vergesst es 😃 😉
    geloescht



  • Also ich würde eine map nehmen. Da hast du eine akzeptable Geschwindigkeit.


Anmelden zum Antworten