Lottozahlenprogramm Hilfe!



  • Guten Morgen

    also mein problem ist bin im anfang meiner Ausbildung und wir müssen

    für die schule einen Lottorechner schreiben der folgendes können soll

    -angabe wie viele zeihungen gemacht werden sollen
    -keine doppelten zahlen bei der ausgabe
    -und sortiert ausgeben
    -preisberechnung

    leider bin ich totaler anfänger und hab gerade mal programme wie hello world und sowas geschrieben eben den anfang also ich will jetzt nicht das mir einer hier die Hausaufgaben macht ^^ sondern nur ich bekomme das mit der schleife und dem array überhaupt nicht hin und sonst find ich nur ohne abfragen hilfe im netzt wär nett wen mir einer helfen könnte danke.

    Hier mal mein warscheinlich misslungener anfang.
    benutze Dev cpp

    [code="cpp"]

    #include <cstdlib>
    #include <iostream>

    using namespace std;

    int main(int argc, char *argv[])
    {
    int i,ziehungen = 0;

    cout<< "Bitte geben sie die Anzahl der Ziehungen ein die sie Tätigen wollen.(Max 12)"<<endl;

    cin>> i;

    for (i = 0; i <= ziehungen;i++)

    system("PAUSE");
    return EXIT_SUCCESS;
    }



  • Deine Schleife zählt zu weit!

    Nicht: ... i <= ziehungen ...
    sondern: ... i < ziehungen ...

    Was willst Du mit einem Array? Du brauchst keines. Nimm stattdessen einen Vektor, fülle ihn mit den Zahlen 1 - 49, benutze die shuffle-Funktion aus der STL, um ihn zu mischen, fülle die ersten 6 Zahlen in einen neuen Vektor, sortiere ihn mittels der sort-Funktion aus der STL und gib ihn aus ...
    Damit hast Du eine Ziehung fertig.



  • Sieht ja schonmal ganz gut aus. Erstmal solltest du prüfen ob die Eingabe geklappt hat und ob der Wert auch wirklich >0 und <= 12 ist. Nun mach dir einen Vektor indem du die gezogegen Zahlen speicherst.

    Ein Schleifendurchgang wählt eine zufällige Zahl (die sich halt im Bereicht befindet in welchem deine Zahlen sein dürfen) und fügt sie am Ende des Vektors hinzu. Bevor du die zufällige Zahl aber hinzufügst, prüfst du, ob die bisherigen Zahlen im Vektor nicht gleich sind wie die, die du eben gezogen hast.

    Dann nachdem du alle Zahlen gezogen hast, sortierst du sie. Das musst du aber nicht selbst machen da es dafür die Funktion std::sort gibt. Hier steht was sie macht und wie man sie nutzt.

    Was du mit "preisberechnung" meinst ist mir nicht so ganz klar aber das ist ja erst der letzte Punkt.

    PS: Ich könnte dir natürlich auch die fertige Lösung geben aber das mach ich nicht weil du sonst nichts lernst sondern einfach nur kopierst.



  • Zu langsam. Belli's Lösung ist natürlich um ein Vielfaches eleganter...


  • Mod

    Elraser1993 schrieb:

    leider bin ich totaler anfänger und hab gerade mal programme wie hello world und sowas geschrieben eben den anfang also ich will jetzt nicht das mir einer hier die Hausaufgaben macht

    Dann ist die Aufgabe vermutlich viel zu schwer. Kann es sein, dass du so einiges verpasst hast?

    Wenn du die fertigen Algorithmen aus der Standardbibliothek nehmen kannst/sollst, dann wäre die Aufgabe einfach, da dann die schwierigen Teile (keine doppelten Zahlen, Sortieren) zu Einzeilern werden. Jedoch nehme ich mal an, dass dir diese Funktionen nicht bekannt sind und ihr diese auch nicht benutzen dürft. Falls doch, ist der Rest bloß ein paar Schleifen, dafür hast du den Ansatz ja schon selber hinbekommen.

    Belli schrieb:

    ülle die ersten 6 Zahlen in einen neuen Vektor, sortiere ihn mittels der sort-Funktion

    Sortier doch einfach die ersten sechs Zahlen.

    Übrigens mag ich diese Lösung nicht, weil sie bei einer großen Grundmenge versagt. Wenn ich mich recht an alte Lottothreads erinnere war bei 6 aus 49 die Performancereihenfolge:
    1. Neuziehen einer Zahl bei doppelter Zahl (wird aber sehr schlecht, wenn die Anzahl der gezogenen Zahlen gegen die Grundmenge geht)
    2. Algorithmus, bei dem die Menge der möglichen ziehbaren Zahlen sich anpasst (ist immer gleich gut, aber manchmal eben nicht so gut wie 1.)
    3. random_shuffle (st immer schlecht, wird noch schlechter bei großen Grundmengen)



  • Diese Zeile würde ich noch einmal überdenken:

    cin>> i;
    


  • Okay ohne Array also und wie sieht so ein vektor aus verstehe es nicht so richtig mache es heute zum zweiten mal ^^



  • ja das stimmt finde es wirklich ziemlich schwer ist auch meine erste Programmiersprache die ich lerne versuche mir viel selbst bei zu bringen was leider nicht ganz so gut klappt

    naja habe wenigstens hinbekommen das er mir jetzt schonmal die pausen zeile der anzahl meiner eingabe ausgibt 😃

    #include <cstdlib>
    #include <iostream>

    using namespace std;

    int main(int argc, char *argv[])
    {
    int i,ziehungen = 0;

    cout<< "Bitte geben sie die Anzahl der Ziehungen ein die sie Tätigen wollen.(Max 12)"<<endl;

    cin>> ziehungen;

    for (i = 0; i < ziehungen;i++)

    system("PAUSE");
    return EXIT_SUCCESS;
    }


  • Mod

    Elraser1993 schrieb:

    ja das stimmt finde es wirklich ziemlich schwer ist auch meine erste Programmiersprache die ich lerne versuche mir viel selbst bei zu bringen was leider nicht ganz so gut klappt

    naja habe wenigstens hinbekommen das er mir jetzt schonmal die pausen zeile der anzahl meiner eingabe ausgibt 😃

    Wie stellst du dir denn weitere Hilfe vor? Die Aufgabe liegt weit über deinen Fähigkeiten. Die von Belli gegebene Hilfestellung hast du nicht einmal verstanden, da dir das nötige Hintergrundwissen fehlt. Dabei war das die einfachstmögliche Lösung, eigentlich sogar geschummelt, denn ich nehme mal an, du sollst selber die Sortierfunktion und eine Funktion zur einmaligen Ziehung schreiben. Das wird nichts, wenn dir einfache Schleifen schon Schwierigkeiten machen. Sollen wir das Programm Zeile für Zeile für dich schreiben?

    Wenn du dich eine Woche lang hinsetzt und intensiv den Stoff nachholst, dann bist du so weit, dass du die Aufgabe lösen kannst. Wahrscheinlich sogar alleine. Aber bloß mit "Hello World"-Niveau ist das aussichtslos. Klingt hart, ist aber eben so.



  • Elraser1993 schrieb:

    ja das stimmt finde es wirklich ziemlich schwer ist auch meine erste Programmiersprache die ich lerne versuche mir viel selbst bei zu bringen was leider nicht ganz so gut klappt

    naja habe wenigstens hinbekommen das er mir jetzt schonmal die pausen zeile der anzahl meiner eingabe ausgibt 😃

    #include <cstdlib>
    #include <iostream>

    using namespace std;

    int main(int argc, char *argv[])
    {
    int i,ziehungen = 0;

    cout<< "Bitte geben sie die Anzahl der Ziehungen ein die sie Tätigen wollen.(Max 12)"<<endl;

    cin>> ziehungen;

    for (i = 0; i < ziehungen;i++)

    system("PAUSE");
    return EXIT_SUCCESS;
    }

    Weshalb initialisierst du i 2 x mit 0 hat das einen bestimmten Grund ?
    Wenn du aber wie du schreibst grade erst das Hello World Programm geschrieben hast ( sprich grade erst dich mit ein/ausgabe beschäftigt hast) denke ich ist dass was du jetzt vorhast ne Nummer zu groß für dich.Ich verstehe aber auch absolut nicht ,weshalb ihr in der Schule direkt nach dem Hallo Welt Prog mit sowas wie du jetzt vorhast weitermacht ,oder hast du einfach ne menge verpasst / warst krank o.ä.?



  • int i, ziehungen = 0;
    initialisiert nur ziehungen ...



  • #include <iostream>
    #include <vector>
    #include <ctime>
    
    template<typename T>
    void swap(T &var1, T &var2) {
    	T temp = var1;
    	var1 = var2;
    	var2 = temp;
    }
    
    template<typename T>
    void mix_vector(std::vector<T> &vec) {
    	srand((unsigned)time(NULL));
    	for(size_t i = 0; i < vec.size(); ++i) {
    		size_t ran_num1 = rand() % vec.size();
    		size_t ran_num2 = rand() % vec.size();
    		swap(vec[ran_num1], vec[ran_num2]);
    	}
    }
    
    template<typename T>
    void bubble_sort(std::vector<T> &vec) {
    	bool swapped;
    	do {
    		swapped = false;
    		for(size_t i = 0; i < vec.size()-1; ++i) {
    			if(vec[i] > vec[i+1]) {
    				swap(vec[i], vec[i+1]);
    				swapped = true;
    			}
    		}
    	} while(swapped);
    }
    
    int main() {
    	const int LOTTO_NUMS = 49;
    	int max_nums;
    	do {
    		std::cout << "Anzahl der Lottozahlen, die gezogen werden sollen: ";
    		std::cin >> max_nums;
    	} while(max_nums < 1 || max_nums > 12);
    
    	std::vector<unsigned int> lotto_nums(LOTTO_NUMS);
    	for(size_t i = 0; i < lotto_nums.size(); ++i)
    		lotto_nums[i] = i+1;
    
    	mix_vector(lotto_nums);
    
    	for(size_t i = 0; i < LOTTO_NUMS-max_nums; ++i)
    		lotto_nums.pop_back();
    
    	bubble_sort(lotto_nums);
    
    	std::cout << "Die " << max_nums << " Lottozahlen lauten: ";
    	for(int i = 0; i < max_nums; ++i)
    		std::cout << lotto_nums[i] << ' ';
    }
    


  • Achso, ähm... Der vector ist einfach eine sicherere Methode als new und delete zu benutzen.
    Ist also ziemlich leicht wie du siehst.



  • Ich frage mich wie man bei solchen Fragestellungen/Fragern noch antwortet.
    Und ihr habt ja echt teilweise noch Hoffnung, dass es den Fragestellern wichtig ist oder die sich mit der Materie beschäftigen oO



  • Skym0sh0 schrieb:

    Ich frage mich wie man bei solchen Fragestellungen/Fragern noch antwortet.
    Und ihr habt ja echt teilweise noch Hoffnung, dass es den Fragestellern wichtig ist oder die sich mit der Materie beschäftigen oO

    Wenn es wirklich eine Hausaufgabe ist, dann muss er sich wohl damit beschäftigen, denn sonst wird er bald ein richtiges Problem in der Schule / Uni haben. Was er daraus macht ist nicht mein Ding.



  • #include <iostream>
    #include <vector>
    #include <ctime>
    
    template<typename T>
    void swap(T &var1, T &var2) {
    	T temp = var1;
    	var1 = var2;
    	var2 = temp;
    }
    //Ok, aber std::swap würde uch gehen. Sagen wir mal, außer std::vector will man 
    //die STL meiden. 
    
    template<typename T>
    void mix_vector(std::vector<T> &vec) {
    	srand((unsigned)time(NULL));//Nicht hier. Immer nur am ANfang der main()
    	for(size_t i = 0; i < vec.size(); ++i) {//Warum alle und nicht nur max_nums?
    		size_t ran_num1 = rand() % vec.size();//Ungeschickt. http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
    		size_t ran_num2 = rand() % vec.size();
    		swap(vec[ran_num1], vec[ran_num2]);
    	}
    }
    
    template<typename T>
    void bubble_sort(std::vector<T> &vec) {
    	bool swapped;
    	do {
    		swapped = false;
    		for(size_t i = 0; i < vec.size()-1; ++i) {
    			if(vec[i] > vec[i+1]) {
    				swap(vec[i], vec[i+1]);
    				swapped = true;
    			}
    		}
    	} while(swapped);
    }
    //statt swapped ist es geschickter, den maximalen Index sich zu merken, wo 
    //noch eine Vertauschung stattgefunden hatte und im nächsten Durchlauf bis 
    //dahin nur zu laufen. 
    
    int main() {
    	const int LOTTO_NUMS = 49;
    	int max_nums;
    	do {
    		std::cout << "Anzahl der Lottozahlen, die gezogen werden sollen: ";
    		std::cin >> max_nums;
    	} while(max_nums < 1 || max_nums > 12);
    
    	std::vector<unsigned int> lotto_nums(LOTTO_NUMS);
    	for(size_t i = 0; i < lotto_nums.size(); ++i)
    		lotto_nums[i] = i+1;
    
    	mix_vector(lotto_nums);
    
    	for(size_t i = 0; i < LOTTO_NUMS-max_nums; ++i)
    		lotto_nums.pop_back();
    //lotto_nums.resize(max_nums);
    
    	bubble_sort(lotto_nums);
    
    	std::cout << "Die " << max_nums << " Lottozahlen lauten: ";
    	for(int i = 0; i < max_nums; ++i)
    		std::cout << lotto_nums[i] << ' ';
    }
    


  • Skym0sh0 schrieb:

    Ich frage mich wie man bei solchen Fragestellungen/Fragern noch antwortet.
    Und ihr habt ja echt teilweise noch Hoffnung, dass es den Fragestellern wichtig ist oder die sich mit der Materie beschäftigen oO

    ich unterstelle mal, Du meinst hier nicht 'wie' sondern 'wieso man überhaupt antwortet'. Nun ich meinerseits neige dazu, in dieser Weise zu antworten:

    #include <iostream>
    #include <algorithm> // copy, iter_swap
    #include <iterator> // ostream_iterator
    #include <numeric> // partial_sum
    #include <vector>
    #include <ctime> // std::time
    #include <cstdlib> // std::rand
    
    template< typename I, typename F >
    void random_drawing( I from, I to, I last, F rnd )
    {
        using std::iter_swap;
        const std::ptrdiff_t sz = last - from;
        for( I i = from; i != to; ++i )
            iter_swap( i, from + rnd() % sz );
    }
    
    int main()
    {
        using namespace std;
        srand( static_cast< unsigned int >(time(nullptr)) );
        const int N = 6;
        vector< int > zahlen( 49, 1 );
        partial_sum( begin(zahlen), end(zahlen), begin(zahlen) ); // alle Zahlen von 1 bis 49
    
        int anzBloecke;
        cout << "Wieviel Bloecke wollen Sie spielen? ";
        if( cin >> anzBloecke ) // warum das hier auf 12 begrenzen?
        {
            for( int block=1; block<=anzBloecke; ++block )
            {
                random_drawing( begin(zahlen), begin(zahlen)+N, end(zahlen), std::rand ); // Ziehung von N Zahlen
                // --   sortieren und ausgeben
                sort( begin(zahlen), begin(zahlen)+N );
                copy(  begin(zahlen), begin(zahlen)+N, ostream_iterator< int >( cout << block << ".Block: ", " " ) );
                cout << endl;
            }
        }
        return 0;
    }
    

    jetzt gibt es den Fragesteller betreffend mehrere Möglichkeiten:
    1.) der Fragesteller versteht nichts und ignoriert die Antwort
    2.) der Fragesteller gibt den Code als seine Hausarbeit ab und der Lehrer/Dozent sieht, dass sich das der Fragesteller nicht selbst erarbeitet haben kann und gibt ihm eine schlechte Note.
    3.) (wie 2.) aber der Lehrer/Dozent akzeptiert das - dann ist er selber Schuld, die Noten an diesem Institut sind eh' nichts wert
    4.) der Fragesteller versteht die Antwort zwar nicht, meint aber dass das so ok ist und beginnt, sich mit der Materie zu beschäftigen und gezielt nachzufragen.

    Das wären IMHO die Möglichkeiten mit fallender Wahrscheinlichkeit. Fall 4 würde mir am besten gefallen, aber passiert fast nie.
    Und warum mache ich das jetzt (oder WTFIsUrQ, oder sonst wer) und das obwohl man manchmal dafür geschlagen wird oder die Antwort sofort vom Moderator gelöscht wird? - die Wahrheit ist: just coding for fun.

    volkard schrieb:

    template<typename T>
    void swap(T &var1, T &var2) { ...}
    //Ok, aber std::swap würde uch gehen. Sagen wir mal, außer std::vector will man 
    //die STL meiden.
    

    warum eigentlich? STL von Anfang an - std::swap ist wirklich nicht schwer zu verstehen.

    Gruß
    Werner



  • Werner Salomon schrieb:

    template< typename I, typename F >
    void random_drawing( I from, I to, I last, F rnd )
    {
        using std::iter_swap;
        const std::ptrdiff_t sz = last - from;
        for( I i = from; i != last; ++i )
            iter_swap( i, from + rnd() % sz );
    }
    

    to wird gar nicht benutzt. So, wie es jetzt ist, wär ich mir gar nicht sicher, ob das einer Gleichverteilung von Permutationen entspricht. Und dabei meine ich jetzt gar nicht, dass ggf rnd()%sz keine Gleichverteilung hat. Ich würde das noch so modifizieren:

    template< typename I, typename F >
    void random_drawing( I from, I to, I last, F rnd )
    {
        using std::iter_swap;
        std::ptrdiff_t sz = last - from;
        for( I i = from; (i != to) && sz>1; ++i, --sz )
    //                   ^^^^^^^^^^^^^^^^^       ^^^^
            iter_swap( i, i + rnd() % sz );
    //                    ^
    }
    


  • Werner Salomon schrieb:

    volkard schrieb:

    template<typename T>
    void swap(T &var1, T &var2) { ...}
    //Ok, aber std::swap würde uch gehen. Sagen wir mal, außer std::vector will man 
    //die STL meiden.
    

    warum eigentlich? STL von Anfang an - std::swap ist wirklich nicht schwer zu verstehen.

    Vielleicht weil die Aufgabe möglicherweise nicht mit STL-Algorithmen gelöst werden darf?

    Klar, schwer zu verstehen ist das alles nicht. Ich gehe aber davon aus, dass Sachen wie sort und copy zu Übungszwecken selbst implementiert werden sollen. Schlimmstenfalls hat auch der Lehrer noch nie was von STL gehört und kann damit nichts anfangen. Sollte nicht sein, lässt sich aber nicht ausschließen.



  • Autsch - mit dem 'to' hast Du völlig Recht, so hätte man auch std::random_shuffle nehmen können - ich hab's korrigiert. Das war vorher auch so, aber ich hatte die Variablen umbenannt.

    Die Sache mit der Gleichverteilung ist die Frage. Den Gedanken hatte ich auch, sah aber keinen Grund es nicht so zu machen. Ich denke hier http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle steht einiges zum Thema - bin gerade beim Durchlesen.

    Gruß
    Werner

    PS.: @volkard: Danke für den Link.


Anmelden zum Antworten