Benötige Hilfe! Zufallszahlen eingrenzen (Lotto)



  • volkard schrieb:

    brotbernd schrieb:

    class SupaDupaDistribution
    {
    public:
     SupaDupaDistribution() : ..., dist(0,49), ... {}
     unsigned int operator()()
     {
      unsigned int n = dist(eng);
      if (good(n)) return n;
      else nochmal //(bzw while nicht good)
     }
    private:
     size_t count, odd, sum usw...
     std::mt19937 eng; // o.a.
     std::uniform_int<unsigned int> dist;
    };
    

    Was soll das denn?

    Das ist ne Mischung aus C++ und Pseudocode 😃
    Ziehe ne Zufallszahl so lange sie bestimmte Bedingungen erfüllt. Ich dachte das könne man vielleicht daraus ablesen.



  • ja das hab ich auch nich kapiert was da steht...

    sack und asche wenn ich bei einer do-while-schleife eine UND bedingung festlegen will könnte das doch so aussehen?

    do
    {
    blablabla
    }
    while ( summe >= 142 && summe <= 156);

    er soll nur weiter machen im programm, wenn die zahl aus bla bla zwischen 142 und 156 liegt!
    das macht er irgendwie nicht er beachte irgendwie nur die erste regel.

    und kann ich dann noch mehrere bedingungen in die gleiche klammer einbauen? wieviele?


  • Mod

    keyzer777 schrieb:

    er soll nur weiter machen im programm, wenn die zahl aus bla bla zwischen 142 und 156 liegt!
    das macht er irgendwie nicht er beachte irgendwie nur die erste regel.

    Das ist aber richtig, so wie es da steht. Du hast vermutlich noch einen anderen Fehler im Programmablauf.

    und kann ich dann noch mehrere bedingungen in die gleiche klammer einbauen? wieviele?

    So viele wie du willst. Achte bei komplizierten logischen Ausdrücken aber auf die Rangfolge der Operatoren und setz gegebenenfalls Klammern.



  • keyzer777 schrieb:

    do
    {
    blablabla
    }
    while ( summe >= 142 && summe <= 156);

    er soll nur weiter machen im programm, wenn die zahl aus bla bla zwischen 142 und 156 liegt!

    Da steht aber: tue blablabla solange summe zwischen 142 und 156 und nicht höre auf wenn ...
    Wenn der Ausdruck in while() wahr ist, wird die Schleife wiederholt.


  • Mod

    brotbernd schrieb:

    Da steht aber: tue blablabla solange summe zwischen 142 und 156 und nicht höre auf wenn ...
    Wenn der Ausdruck in while() wahr ist, wird die Schleife wiederholt.

    Ach so war das gemeint mit dem "weitermachen". Ich hatte gedacht "mach weiter mit der Schleife" wäre gemeint. war schon total verwirrt, wie man bei der Konstruktion etwas falsch machen kann.

    @keyzer777: Ein paar Vokabeln Englisch helfen solche Fehler in Zukunft zu vermeiden.



  • SeppJ schrieb:

    @keyzer777: Ein paar Vokabeln Englisch helfen solche Fehler in Zukunft zu vermeiden.

    Vielleicht mit REPEAT UNTIL verwechselt.. 😉



  • Müsste nicht das hier auch gehen (Nur auf die schnelle hingeklatscht):

    bool weiter = false;
    int summe;
    int i = 0; // Durchgänge
    
    while(!weiter && i < 6)
    {
           // Berechnungen rein usw.
    
        if(summe >= 142 && summe <= 156)
        {
            weiter = true;
        }
    }
    

  • Mod

    🙂 schrieb:

    Müsste nicht das hier auch gehen (Nur auf die schnelle hingeklatscht):

    Ja, aber wieso sollte man so etwas tun? 😕



  • 🙂 schrieb:

    Müsste nicht das hier auch gehen (Nur auf die schnelle hingeklatscht):

    bool weiter = false;
    int summe;
    int i = 0; // Durchgänge
    
    while(!weiter && i < 6)
    {
           // Berechnungen rein usw.
    
        if(summe >= 142 && summe <= 156)
        {
            weiter = true;
        }
    }
    

    .........!!



  • keyzer777 schrieb:

    Da ich leider schon länger nicht mehr mit C++ gearbeitet hat komme ich zur Zeit da nicht weiter und hoffe das mir hier vielleicht jemand etwas unter die Arme greifen kann.

    Hallo keyzer,

    unabhängig davon, ob Du mit C++ oder einer anderen Sprache arbeitest, sollte man sich vorher überlegen, wie man sein Problem in kleine handliche Teile zerlegen kann. In Deinem Fall gibt es eine Menge verschiedener Möglichkeiten - eine naheliegende, die hier auch schon angewendet wurde, ist:

    1.) 6 verschiedene Zahlen aus 1 bis 49 bestimmen
    2.) prüfen, ob diese die gewünschten Eigenschaften haben
    3.) wenn nein, dann bei 1.) weitermachen
    4.) Zahlen ausgeben

    Allein für den Teil 1.) ist hier im Forum schon einiges gesagt worden, suche einfach mal nach dem Stichwort 'Lotto'. Um 6 paarweise verschieden(!) Zahlen aus 1 bis 49 zu bestimmen gibt es im wesentlichen zwei Möglichkeiten:

    1a) bestimme eine Zahl zwischen 1 bis 49
    1b) falls sie noch nicht im Ergebnis vorkommt, füge sie hinzu
    1c) falls noch keine 6 Zahlen beisammen sind, mache bei 1a) weiter

    oder

    1a) generiere eine Menge von Zahlen von 1 bis 49
    1b) mache 6 mal:
    1c) wähle zufällig eine Zahl aus der Menge aus und lösche sie dort und füge sie dem Ergebnis hinzu

    Die erste Variante ist vielleicht einfacher zu codieren, aber hat u.a. den Nachteil, dass sie länger dauert, wenn eine Zahl ausgewählt wird, aber nur noch wenige zur Auswahl stehen. Bei 6 aus 49 ist das noch kein Problem, aber da Du weitere Bedingungen eingeführt hast, die die Auswahl irgendwann einschränken, würde ich hier die zweite Variante wählen.

    Dazu baue ich zunächst eine Klasse, die den Pott von 49 Kugeln (jede Kugel mit einer Zahl drauf) modelliert. Dort kann man zufällig Zahlen entnehmen.

    #include <cstdlib> // rand, srand
    #include <iostream>
    #include <ctime> // time()
    #include <vector>
    
    class _49
    {
    public:
        _49() : m_kugeln()
        {
            // hier wird 'm_kugeln' mit den Werten von 1 bis 49 gefüllt
            for( int kugel = 1; kugel <= 49; ++kugel )
                m_kugeln.push_back( kugel );
        }
    
        // --   liefert zufällig eine der noch enthaltenen Kugeln und entfernt sie aus der Menge
        int zieheEineKugel()
        {
            init();
            using namespace std;
            const vector< int >::iterator zufaelligerIndex 
                = m_kugeln.begin() + int( (rand() / (RAND_MAX+1.0)) * m_kugeln.size() );
            const int gezogeneKugeln = *zufaelligerIndex;
            m_kugeln.erase( zufaelligerIndex );
            return gezogeneKugeln;
        }
    
    private:
        static void init()
        {
            if( !m_initialized )
            {
                using namespace std;
                srand( static_cast< unsigned int >( time(0) ) );
                m_initialized = true;
            }
        }
        static bool m_initialized;
        std::vector< int > m_kugeln;
    };
    
    bool _49::m_initialized = false;
    
    int main()
    {
        using namespace std;
        _49 kugeln;
        for( int i = 0; i < 6; ++i )
            cout << kugeln.zieheEineKugel() << endl; 
        return 0;
    }
    

    im main() ist ein einfaches Beispiel, wie diese Klasse zu benutzen ist. Also einfach ein Objekt mit diesem Typ anlegen - hier 'kugeln' und dann immer eine ziehen. Es ist garantiert, dass Du nie zwei Kugeln mit dem gleichem Wert ziehst.

    Jetzt gehe ich einen kleinen Schritt weiter und betrachte die Ziehung der 6 Kugeln als Einheit. Ziel ist es, eine Ziehung vom einem Algorithmus generieren zu lassen

    #include <algorithm> // copy
    #include <cstdlib> // rand, srand
    #include <ctime> // time()
    #include <iostream> 
    #include <iterator> // ostream_iterator
    #include <set>
    #include <vector>
    
    class _49 ... // wie oben
    
    // --   liefert 6 'Kugeln' aus 1 bis 49
    std::set< int > ziehung_6_aus_49()
    {
        _49 kugeln;
        std::set< int > ergebnis;
        for( int i=0; i<6; ++i )
            ergebnis.insert( kugeln.zieheEineKugel() );
        return ergebnis;
    }
    
    int main()
    {
        using namespace std;
        set< int > gezogenenKugeln = ziehung_6_aus_49();
    
        // --   Ergebnis der Ziehung ausgeben
        copy( gezogenenKugeln.begin(), gezogenenKugeln.end(), ostream_iterator< int >( cout, " " ) );
        cout << endl;
        return 0;
    }
    

    damit wäre der oben erwähnte Teil 1 erledigt; und Teil 4 bei der Gelegenheit auch - sonst sieht man ja nicht, ob Teil 1 erfolgreich war 😉

    Jetzt zu "2.) prüfen, ob diese die gewünschten Eigenschaften haben".
    Hier kann man massiv Algorithmen aus dem C++-Standard einsetzen. Zusammen mit dem Funktoren aus <functional>. Ich unterstelle mal, dass Du damit nicht vertraut bist, aber ich versuch' es trotzdem mal - wir sind ja hier schließlich im C++-Forum und das ist alles Standard!

    #include <algorithm> // copy
    #include <cassert>
    #include <cmath> // abs
    #include <cstdlib> // rand, srand
    #include <ctime> // time()
    #include <functional> // bind*, less, usw.
    #include <iostream> 
    #include <iterator> // ostream_iterator
    #include <numeric> // accumulate
    #include <set>
    #include <vector>
    
    class _49 ... // wie oben
    
    // --   liefert 6 'Kugeln' aus 1 bis 49
    std::set< int > ziehung_6_aus_49() .. // wie oben
    
    struct istPaerchen : std::binary_function< int, int, bool >
    {
        // liefert true, falls a und b ein Pärchen sind
        result_type operator()( first_argument_type a, first_argument_type b ) const
        {
            return std::abs( a - b ) == 1;
        }
    };
    
    // --   liefert 'true', falls die Menge der gezogenen Kugeln im Intervall [first,last)
    //      die Anforderungen erfüllt
    template< typename T >
    bool passt( T first, T last )
    {
        using namespace std;
        assert( distance( first, last ) == 6 );
        const int summe = accumulate( first, last, 0 );
        return 
            summe >= 142 && summe <= 156 // 142 <= summe <= 256
            && count_if( first, last, bind2nd( less< int >(), 25 ) ) == 2 // 2 mal x < 25
            && count_if( first, last, bind2nd( greater< int >(), 25 ) ) == 4 // 4 mal x > 25
            && count_if( first, last, bind2nd( modulus< int >(), 2 ) ) == 4 // 4 mal x ist ungerade (=> 2 mal gerade)
            && adjacent_find( first, last, istPaerchen() ) != last // mindestens ein Pärchen existiert
            ;
    }
    
    int main()
    {
        using namespace std;
        set< int > gezogenenKugeln = ziehung_6_aus_49();
    
        // --   Ergebnis der Ziehung ausgeben
        copy( gezogenenKugeln.begin(), gezogenenKugeln.end(), ostream_iterator< int >( cout, " " ) );
        cout << endl;
    
        cout << "Die Ziehung erfuellt " << (passt( gezogenenKugeln.begin(), gezogenenKugeln.end() )? "" : "NICHT") << " die Anforderungen" << endl;
        return 0;
    }
    

    Neu ist der Algorithmus 'passt()', der aus einer Menge von (6) 'Kugeln' bestimmt, ob die von Dir gesetzten Anforderungen erfüllt sind.

    Wenn Du dieses Programm jetzt ein paar Mal ausführst, so wirst Du merken, dass Deine Anforderungen praktisch nie erfüllt sind. Nach meiner Abschätzung wirst Du das Programm im Mittel 280 Mal aufrufen, bevor es einmal meldet 'Anforderungen erfüllt'. Das geht natürlich einfacher in einer Schleife, und damit sind wir bei

    "3.) wenn nein, dann bei 1.) weitermachen" .. und dazu muss man nur noch das main() erweitern:

    int main()
    {
        using namespace std;
        set< int > gezogenenKugeln;
        do
        {
            gezogenenKugeln = ziehung_6_aus_49();
        }
        while( !passt( gezogenenKugeln.begin(), gezogenenKugeln.end() ) ); // wiederholen, solange es nicht passt
    
        // --   Ergebnis der Ziehung ausgeben
        copy( gezogenenKugeln.begin(), gezogenenKugeln.end(), ostream_iterator< int >( cout, " " ) );
        cout << endl;
        return 0;
    }
    

    .. das soll für's erste reichen.

    Gruß
    Werner



  • int( (rand() / (RAND_MAX+1.0)) * m_kugeln.size() );
    

    Den Trick werde ich nie verstehen. Jetzt sind nicht mehr die ersten 36 Zahlen um 0.1497% häufiger, sondern die Häufigeren Zahlen verteilen sich jetzt gleichmäßig über das Intervall.
    Klingt für mich nach Mystik wie

    srand(time(0)*time(0));
    

    Mein Tipp: Entweder nicht machen oder richtig machen.



  • Hallo keyzer,

    Du wirst vielleicht einwenden, dass mein Vorschlag viel zu kompliziert ist, und nicht mehr macht, als der von matze-o - mal abgesehen davon, dass er die 25 vergessen hat. OK - ich meine komplizierter ist er gar nicht, sondern nur ungewohnt bzw befremdlich für jemanden der das so nicht kennt.

    Ein Vorteil liegt darin, dass man den Vorgang der Ziehung jetzt ändern kann, ohne sich mit dem, Rest herumschlagen zu müssen. Ich hatten im ersten Beitrag schon erwähnt, dass es mehr als eine Möglichkeit gibt, zu den von Dir gewünschten Lottozahlen zu kommen. Ein großer Nachteil der bisher vorgestellten Lösungsmöglichkeit ist der Aufwand so viele Lottoziehungen machen zu müssen, bis das gewünschte dabei ist. Die zweite Möglichkeit, die ich hier vorstellen will, soll diesen Nachteil beheben.

    1.) generiere den 'Pott' mit 49 Kugeln (class _49)
    2.) mache folgendes 6 mal
    3.) prüfe ob noch Kugeln vorhanden sind, falls nein beginne von vorn (-> 1.)
    4.) ziehe zufällig eine Kugel und füge sie dem Ergebnis hinzu
    5.) beseitige alle Kugeln aus dem Pott, die zusammen mit den bereits gezogenen Kugeln nicht mehr in Frage kommen
    5.a) -- Ende der Schleife 2.)
    6.) Ergebnis ausgeben

    Das Problem dabei ist, dass das gar nicht so einfach ist, zu bestimmen, welche Kugeln noch in Frage kommen und welche nicht. Deshalb wähle ich einen gemischten Ansatz, wo am Ende immer noch geprüft wird, ob die Anforderungen passen.

    Zunächst muss aber _49 noch etwas erweitert werden, Kugeln sollen entfernt werden können und eine Abfrage, ob keine Kugeln mehr da sind, fehlt noch

    class _49
    {
    public:
        _49(); // wie oben
        int zieheEineKugel(); // wie oben
    
        // --   entfernt alle Kugeln mit der Eigenschaft 'pred( kugel ) == true'
        template< typename F >
        void remove_if( F pred )
        {
            m_kugeln.erase( std::remove_if( m_kugeln.begin(), m_kugeln.end(), pred ),
                m_kugeln.end() );
        }
    
        bool empty() const { return m_kugeln.empty(); }
    
    private:
        static void init(); // wie oben
        static bool m_initialized;
        std::vector< int > m_kugeln;
    };
    

    Um die oben beschriebene Vorgehensweise zu erreichen, erweitere ich den Algorithmus der Ziehung

    template< typename T >
    struct KeinPaerchenMoeglich_type : std::unary_function< int, bool >
    {
        KeinPaerchenMoeglich_type( T first, T last )
            : m_first( first ), m_last( last )
        {} 
        result_type operator()( argument_type a ) const
        {
            return std::find_if( m_first, m_last, std::bind2nd( istPaerchen(), a ) ) == m_last;
        }
    private:
        T m_first, m_last;
    };
    template< typename T >
    KeinPaerchenMoeglich_type< T > keinPaerchenMoeglich( T first, T last )
    {
        return KeinPaerchenMoeglich_type< T >( first, last );
    }
    
    std::set< int > ziehung_6_aus_49_b()
    {
        using namespace std;
        std::set< int > ergebnis;
        do
        {
            ergebnis.clear(); // wg. Wiederholungen
            _49 kugeln;
            bool geradeZahlenEntfernt = false;
            bool ungeradeZahlenEntfernt = false;
            bool kleiner25Entfernt = false;
            bool groesser25Entfernt = false;
            int cntGerade = 0;
            int cntKleiner25 = 0;
            kugeln.remove_if( bind2nd( equal_to< int >(), 25 ) ); // Kugel 25 darf nicht drin vorkommen
            for( int anz = 1; ; ++anz )
            {
                if( kugeln.empty() )
                    break;
                const int kugel = kugeln.zieheEineKugel();
                ergebnis.insert( kugel );
                if( anz == 6 )
                    break;   // <== Schleifenende fertig
    
                if( kugel < 25 )
                    ++cntKleiner25;
                if( kugel % 2 == 0 )
                    ++cntGerade;
    
                if( anz < 2 )
                    continue;
                if( !kleiner25Entfernt && cntKleiner25 == 2 )
                {
                    kugeln.remove_if( bind2nd( less< int >(), 25 ) );
                    kleiner25Entfernt = true;
                }
                if( !geradeZahlenEntfernt && cntGerade == 2 )
                {
                    kugeln.remove_if( not1( bind2nd( modulus< int >(), 2 ) ) );
                    geradeZahlenEntfernt = true;
                }
    
                if( anz < 4 )
                    continue;
                if( !groesser25Entfernt && (anz - cntKleiner25) == 4 )
                {
                    kugeln.remove_if( bind2nd( greater< int >(), 25 ) );
                    groesser25Entfernt = true;
                }
                if( !ungeradeZahlenEntfernt && (anz - cntGerade) == 4 )
                {
                    kugeln.remove_if( bind2nd( modulus< int >(), 2 ) );
                    ungeradeZahlenEntfernt = true;
                }
                if( anz == 5 && adjacent_find( ergebnis.begin(), ergebnis.end(), istPaerchen() ) == ergebnis.end() )
                {
                    kugeln.remove_if( keinPaerchenMoeglich( ergebnis.begin(), ergebnis.end() ) );
                }
            }
        } while( ergebnis.size() < 6 );
        return ergebnis;
    }
    

    der Rest bleibt gleich; lediglich im main muss statt 'ziehung_6_aus_49()' 'ziehung_6_aus_49_b()' aufgerufen werden. Den Prüfer 'passt' könnte man jetzt noch soweit vereinfachen, nur die Summe zu prüfen, der Rest der Anforderungen ist von 'ziehung_6_aus_49_b()' garantiert.

    Gruß
    Werner



  • volkard schrieb:

    int( (rand() / (RAND_MAX+1.0)) * m_kugeln.size() );
    

    Den Trick werde ich nie verstehen.

    das stand mal im Magazin in Marcus' Artikel "Zufälle gibt's". Inzwischen hat er den Artikel aber überarbeitet.

    volkard schrieb:

    Jetzt sind nicht mehr die ersten 36 Zahlen um 0.1497% häufiger, sondern die Häufigeren Zahlen verteilen sich jetzt gleichmäßig über das Intervall.
    Klingt für mich nach Mystik wie

    srand(time(0)*time(0));
    

    Mein Tipp: Entweder nicht machen oder richtig machen.

    Und mein Tipp - nicht nur lästern was falsch ist, sondern auch zeigen, wie es richtig geht.

    Gruß
    Werner



  • Werner Salomon schrieb:

    volkard schrieb:

    Jetzt sind nicht mehr die ersten 36 Zahlen um 0.1497% häufiger, sondern die Häufigeren Zahlen verteilen sich jetzt gleichmäßig über das Intervall.
    Klingt für mich nach Mystik wie

    srand(time(0)*time(0));
    

    Mein Tipp: Entweder nicht machen oder richtig machen.

    Und mein Tipp - nicht nur lästern was falsch ist, sondern auch zeigen, wie es richtig geht.

    Nagut. Besser nicht machen, in beiden Fällen. Und überhaupt ganz oft.
    Das Bißchen Schieflage stört nicht. Falls doch, nehme man erstmal einen Zufallszahlengenerator, der 32-bittige Zahlen liefert. Dann sind die häufigeren nur noch um 0,00000114% häufiger. Falls das noch stört, die kleine Anti-Biasing-Schleife rein, siehe Marc++us.

    Und zum Quadrieren des seeds: Ich denke, es ist offensichtlich, daß das Quadrieren den Zufallsraum beschneidet. Nicht offensichtlich ist nur, wie stark die Beschneidung ist, sagen wir mal >80%.



  • Außerdem habe ich Angst vor Objektorientierung, vor bind, ein wenig vor Templates und vor allem vor Funktionen mit 59 Zeilen (, die die schöne Zufälligkeit nebenbei wieder zerkloppen), aber dafür mag ich funktionale Zerlegung und tue gerne schreiben wie ein N00b.

    #include <iostream>
    #include <cstdlib>
    #include <ctime>
    using namespace std;
    
    bool istSchonDrin(int ziehung[6],int anzahlSchonDrin,int suchzahl){
    	for(int i=0;i!=anzahlSchonDrin;++i)
    		if(ziehung[i]==suchzahl)
    			return true;
    	return false;
    }
    
    int findeNeueZahl(int ziehung[6],int anzahlSchonDrin){
    	int neueZahl;
    	do
    		neueZahl=rand()%49+1;
    	while(istSchonDrin(ziehung,anzahlSchonDrin,neueZahl));
    	return neueZahl;
    }
    
    void erzeugeZiehung(int ziehung[6]){
    	for(int i=0;i!=6;++i)
    		ziehung[i]=findeNeueZahl(ziehung,i);
    }
    
    void printZiehung(int ziehung[6]){
    	for(int i=0;i!=6;++i)
    		cout<<ziehung[i]<<' ';
    	cout<<'\n';
    }
    
    int berechneSumme(int ziehung[6]){
    	int summe=0;
    	for(int i=0;i!=6;++i)
    		summe+=ziehung[i];
    	return summe;
    }
    
    int zaehleZahlenUnter25(int ziehung[6]){
    	int anzahl=0;
    	for(int i=0;i!=6;++i)
    		if(ziehung[i]<25)
    			++anzahl;
    	return anzahl;
    }
    
    int zaehleZahlenUeber25(int ziehung[6]){
    	int anzahl=0;
    	for(int i=0;i!=6;++i)
    		if(ziehung[i]>25)
    			++anzahl;
    	return anzahl;
    }
    
    int zaehleGeradeZahlen(int ziehung[6]){
    	int anzahl=0;
    	for(int i=0;i!=6;++i)
    		if(ziehung[i]%2==0)
    			++anzahl;
    	return anzahl;
    }
    
    int zaehleUngeradeZahlen(int ziehung[6]){
    	int anzahl=0;
    	for(int i=0;i!=6;++i)
    		if(ziehung[i]%2==1)
    			++anzahl;
    	return anzahl;
    }
    
    bool hatZahlenpaeaechen(int ziehung[6]){
    	for(int i=0;i!=6;++i){
    		if(istSchonDrin(ziehung,6,ziehung[i]-1)) return true;
    		if(istSchonDrin(ziehung,6,ziehung[i]+1)) return true;
    	}
    	return false;
    }
    
    int main(){
    	srand(time(0));
    	int ziehung[6];
    	for(;;){
    		erzeugeZiehung(ziehung);
    		int summe=berechneSumme(ziehung);
    		if(summe<142 || summe>156) continue;
    		if(zaehleZahlenUnter25(ziehung)!=2) continue;
    		if(zaehleZahlenUeber25(ziehung)!=4) continue;
    		if(zaehleGeradeZahlen(ziehung)!=2) continue;
    		if(zaehleUngeradeZahlen(ziehung)!=4) continue;
    		if(!hatZahlenpaeaechen(ziehung)) continue;
    		printZiehung(ziehung);
    	}
    	return 0;
    }
    


  • Pöse Purschen dürfen das srand aus der main rausmachen und im global scope

    bool _initRandom=(srand(time(0)),1);
    

    schreiben. Aber das ist nicht im Sinne des happy debugging. Denn auf einmal macht das jeder und falls man mal reproduzierbare Fehler braucht, kann man in der main nicht mehr zurückschalten.



  • Ah, ich weiß, was

    srand(time(0)*time(0));
    

    bringen soll! Nix mit "Das macht man halt so".
    Wenn man das nicht hat und das Programm sekündlich startet, steigt bei vielen Compilern zwischen den Programmläufen die erste erzeugte Zufallszahl jeweils um 1. Das wollte er so wegmachen.

    Besser, mit einer großen ungeraden Zahl plutimizieren. Mal einen normalen LCG angenommen. Ungerade Zahlen sind automatisch teilerfremd zur Zweierpotenz und haben ein Inverses -> kein Bit geht verloren.

    srand(time(0)*67234863);
    

    Dumm nur, wenn es jetzt jemand alle 659479247 Sekunden startet (ja, recht unwahrscheinlich).

    Aber cool ist es erst, einfach ein rand() hinterherzuwerfen, die zweite Zahl ist dann schon so durcheinander, wie es dem rand() halt seine Art ist.

    srand(time(0));rand();
    


  • hallo werner salomon,
    vielen dank das du dir da so viele mühe gemacht hast aber ganz ehrlich, wie du schon gesagt hast, das is ne nummer zu hoch für mich. da hab ich nicht die zeit für mich mit den ganzen befehlen zu beschäftigen die mir fremd sind.
    ich war auf der suche nach einer lösung mir den gewöhnlichen schleifen, if, vor, do-while und was es da noch gibt.

    hallo volkard
    ehrlich ich weiß nicht genau was der befehl
    srand(time(NULL) * time(NULL));
    hab ich halt bei jemandem abgeschrieben der was ähnliches versucht hat.
    bewirkt, aber es funktioniert bei mir. ich bekomme immer 6 unterschiedliche zahlen von 1-49

    nochmal zu meiner do-while-schleife
    ich wollte das das programm nur fortfährt wenn es in blabla eine zahl größer 142 und kleiner 156 errechnet hat.
    mit:

    do
    {
    blablabla
    }
    while ( summe >= 142 && summe <= 156);

    funt das ja nicht.
    hab dann mal rumprobiert und mit:

    do
    {
    do
    {
    blabla
    }
    while (summe >= 157);
    }
    while (summe <= 141);

    macht er das was ich will...



  • Also, die erste do ... while Schleife ist ansich schon korrekt.
    Ich verstehe Dich nicht ganz. Die Leute hier haben Dir wirklich gute Tipps gegeben und Du schlägst alles in den Wind und bist nicht zufrieden. Ich weiß nicht warum Du das Projekt machst, aber wenn Du das gescheit machen willst, dann solltest Du vielleicht mal auf die hören und versuchen zu verstehen.

    Deine Variante der do ... while Schleife kann zu total falschen Verhalten führen. Zum Beispiel wenn die innere Schleife eine Zahl >= 157 bekommt, dann läuft sie durch, obwohl Du willst das die Schleife nur läuft wenn die Zahl <= 156 und >= 142 ist. Das geht nicht gut...


Anmelden zum Antworten