keine doppelten zahlen bei rand()



  • SeppJ schrieb:

    Das ist weder effizient (wie du selber feststellst), noch überhaupt korrekt. Dein Shuffle ist biased und produziert gewisse Folgen häufiger als andere. Probier es mal auf Papier mit 3 Elementen aus.

    Dann finde ich das nicht mehr schick sondern sogar ausgesprochen scheisse.



  • SeppJ schrieb:

    Bei einigen alten Implementierungen (MSVC 6 und älter) ist die Periodenlänge von rand so um die 16 Millionen. Das ist von der gleichen Größenordnung wie die Zahl der Kombinationen von 6 aus 49 (13 Millionen). Das heißt, gewisse Kombinationen zieht man damit auch gerne mal doppelt so oft wie andere, eventuell zieht man manche sogar nie. Man sollte also vielleicht was eigenes implementieren, anstatt zu hoffen, dass rand vernünftig implementiert ist. Die üblichsten Implementierungen haben nämlich auch nur Perioden von 2^31 bis 2^31, was nun auch nicht gerade extrem viel mehr als 13 Millionen ist.

    Man müßte schon sauviel Pech haben, daß die Periode des Programms mit der Periode des Zufallszahlengenerators einen großen gemeinsamen Teiler hat.



  • ich vermute momentan, dass das Problem wohl doch woanders liegt, aber den Fehler im Programm finde ich einfach nicht. Wäre cool wenn der ein oder Andere mir da weiterhelfen könnte 😃

    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <stdbool.h>
    
        double fak (double n){ //Unterfunktion Fakultät
            if(n == 0){
    		return 1;
            }
                else{
        	return n*fak(n-1);
            }
        }
    
    int main(void) {
    
        int Untergrenze = 1;
        int Obergrenze = 49;
        int ziehung = 6;
    
        int sortierung1;
        int sortierung2;
        int zufallszahl;
        double binom = 1;
    
        int i;
        int k;
        int m = 0;
    
        int eingabe[6];
        int Lottozahlen[6];
        int treffer[6];
    
        srand(time(NULL));
    
        printf("Geben Sie bitte 6 Zahlen von 1 - 49 ein um an der Lotterieziehung teilzunehmen.");
    
        for(i=0; i<ziehung; i++) {
            printf("\n\nZahleneingabe: ");
            scanf("%d",&eingabe[i]);
    
            while (eingabe[i]<1) {
            printf("\n\nIhre Eingabe ist kleiner als zulaessig.");
            printf("\nWiederholen Sie die Zahleneingabe. ");
            printf("\n\nZahleneingabe: ");
            scanf("%d",&eingabe[i]);
            }
            while (eingabe[i]>49) {
            printf("\n\nIhre Eingabe ist groesser als zulaessig.");
            printf("\nWiederholen Sie die Zahleneingabe. ");
            printf("\n\nZahleneingabe: ");
            scanf("%d",&eingabe[i]);
            }
        } //Ende FOR-Schleife für Eingabe
    
        printf("\n\nIhre ausgewaehlten Lottozahlen lauten: \n\n");
        printf("1.Auswahl: %d\n",eingabe[0]);
        printf("2.Auswahl: %d\n",eingabe[1]);
        printf("3.Auswahl: %d\n",eingabe[2]);
        printf("4.Auswahl: %d\n",eingabe[3]);
        printf("5.Auswahl: %d\n",eingabe[4]);
        printf("6.Auswahl: %d\n",eingabe[5]);
    
    while (m<3) {
    
            printf("\n\nDie momentanen Lottozahlen lauten: \n\n");
    
            for (i=0; i<ziehung; i++) {
                Lottozahlen[i] = 0;
            }
    
            for (i=0; i<ziehung; i++) {
    
                zufallszahl = 1 + (rand() % 49);
                Lottozahlen[i] = zufallszahl;
    
                if(i>0) {
    
                        if (Lottozahlen[i-1]==Lottozahlen[i]) {
                                Lottozahlen[i] = Lottozahlen[i] +1;
                        }
                }
    
                 if (Lottozahlen[i-1]=Lottozahlen[i]) {
                                Lottozahlen[i] = Lottozahlen[i] +1;
                }
    
            } // Ende FOR-Schleife für Sortierung der Lottozahlen
    
      }
    
                        for(k=0; k<ziehung; k++) {
                                //printf("I: %d\n",i);
                                for(i=0; i<ziehung; i++) {
                                    //printf("K: %d\n",k);
                                    if(eingabe[k]==Lottozahlen[i]) {
                                        treffer[m]=eingabe[k];
                                        m++;
                                    }
                                }
    
                                if(m<3) {
                                    m=0;
                                }
                        }
    
        		//}
    
                for(i=0; i<ziehung; i++){ //Zufallszahlen ausgeben
                    printf("%d.Lottozahl: %d\n",i+1,Lottozahlen[i]);
                }
    
            if (m>2) {
                printf("\nGlueckwunsch, Sie haben %d Zahlen getroffen.\n",m);
                printf("Die folgenden Zahlen sind richtig: ");
                for(i=0;i<m;i++){ //Ausgabe aller richtig getroffenen Zahlen
                            printf("%d ",treffer[i]);
                }
            }
    
    } //Ende While schleife
    
            binom = fak(49)/(fak(6)*fak(43)); //Binomialkoeffizienten berechnen
            printf("\n\nDie Anzahl der moeglichen Ziehungen: %.0lf\n\n", binom);
    
            return 0;
    
    }
    

  • Mod

    Was ist denn überhaupt das Problem? Du schreibst bloß es "funktioniert nicht". Das ist keine Problembeschreibung anhand derer sich irgendjemand mal eben 200 Zeilen Quelltext ansehen wird.



  • Also es handelt sich um ein Programm für die Lottoziehung. Es werden 6 Zahlen von 1-49 eingegeben. Diese werden dann immer mit der zufälligen Zahlenziehung überprüft bis mindestens drei Zahlen übereinstimmen.

    Es müssen bei jeder zufälligen Zahlenziehung unterschiedliche Zahlen kommen, sprich keine doppelten Zahlen bei der momentanen Ziehung. Bei der nächsten Ziehung kann die ein oder andere Zahl ruhig wieder auftauchen solange sie in dieser ziehung nicht zwei oder drei mal auftaucht.

    In meinem Programm jedoch hab ich das Problem, dass das Programm halt paar Sekunden abläuft und mir dann einfach mal in der letzten Ziehung mindestens 3 gleiche Zahlen in der momentanen Ziehung anzeigt.

    Wenn in der momentanen Ziehung zB. eine 3 vorkommt dann darf sie für die nächsten 5 Zahlen nicht wieder vorkommen, sondern erst bei der nächsten Ziehung-


  • Mod

    Wenn das immer noch das Problem ist, dann lies den Thread noch einmal. Die erste Antwort und alles was danach kam, gelten immer noch:

    Furble Wurble schrieb:

    Vielleicht ist Dein Algorithmus um Dubletten festzustellen nicht richtig?

    Wobei man nun das "vielleicht" in der Antwort streichen kann. Denn das hier ist ganz sicher falsch:

    for (i=0; i<ziehung; i++) {
    
                zufallszahl = 1 + (rand() % 49);
                Lottozahlen[i] = zufallszahl;
    
                if(i>0) {
    
                        if (Lottozahlen[i-1]==Lottozahlen[i]) {
                                Lottozahlen[i] = Lottozahlen[i] +1;
                        }
                }
    
                 if (Lottozahlen[i-1]=Lottozahlen[i]) {
                                Lottozahlen[i] = Lottozahlen[i] +1;
                }
    

    Sowohl die Idee (Du vergleichst nur mit dem Vorgänger) als auch die Umsetzung (Was ist bei der ersten Zahl? Du scheinst diesen Fall bedacht zu haben, aber irgendwie auch wieder nicht) und sogar die grundlegende Syntax ('=' ist kein Vergleich!) sind falsch.

    Es wurden reichlich Anregungen in diesem Thread gegeben, wie du selber eine korrekte Prüfung durchführen kannst oder welche alternativen Verfahren geeignet sein könnten, die ganz ohne Prüfung auskommen.



  • genau diese Stelle war auch der Auslöser weshalb ich den Beitrag verfasst habe. Ich habe es mit Tipps die mir zuvor genannt wurden versucht, aber ohne Erfolg es wird trotzdem weiterhin noch bei der letzten Ziehung drei mal die gleiche Zahl gezogen.



  • Du hast da ohne viel Nachdenken hin und her geändert, ohne das eigentliche Problem zu beseitigen.

    Du musst die neue Zahl mit allen bisher gezogenen vergleichen.
    (Ja, das erfordert eine eigene Schleife)

    Bitmapper hatte schon einen Lösungsansatz gepostet: Die Nutzung von Funktionen.

    Und schau dir die Warnungen vom Compiler an. Aktiviere eine hohe Warnstufe, dann passieren solche Fehler wie eine Zuweisung beim if nicht.



  • 1. In deinem Code ist ungefähr jede 3. Zeile falsch, wirf ihn weg und fang von vorne an.
    2. Deine Klammersetzung ist Katastrophal setze jede! Klammer in eine extra Zeile und nur so viele wie nötig.
    3. Nicht nur der Code an sich ist falsch du überprüfst z.B. nicht ob der Benutzer mehrmals die selbe Zahl eingibt und du hast eine Endlosschleife drin, weil du m in jedem Durchlauf der for-Schleife 0 setzt.

    Meine Funktion kannst du übrigens 1 zu 1 in dein Programm übernehen.

    Als Alternative kann ich dir auch die Lösung schicken, das kostet dich dann aber was.



  • Nein danke! Ich hab es vorhin geschafft hab es an zwei Stellen verändert und nun läuft es einwandfrei 😃


Anmelden zum Antworten