Itsjustme Geschrieben 31. Januar 2010 Geschrieben 31. Januar 2010 Hallöchen , habe in der Schule die Aufgabe bekommen einen Lottozahlengenerator zu programmieren . Hab zwar eine Lösung gefunden aber mir stellt sich die Frage, obs da nicht noch ne einfachere Lösung gibt um die gleichen Zahlen , die mit der Methode Random manchmal auftauchen ausschliesst ?? Hier mal mein Code static void Main(string[] args) { int[] array = new int[7]; Random zufallszahl = new Random(); int i = 0 ; array[i] = zufallszahl.Next(1,50); if (array[0] == 0) { i = 0; do { array[0] = zufallszahl.Next(1, 50); i++; } while (i < 1); } else { i = 0; do { array[1] = zufallszahl.Next(1, 50); i++; } while (i < 1); } if (array[1] == array[0]) { i = 0; do { array[1] = zufallszahl.Next(1, 50); i++; } while (i < 1); } else { i = 0; do { array[2] = zufallszahl.Next(1, 50); i++; } while (i < 1); } if (array[2] == array[1] || array[2] == array[0]) { i = 0; do { array[2] = zufallszahl.Next(1, 50); i++; } while (i < 1); } else { i = 0; do { array[3] = zufallszahl.Next(1, 50); i++; } while (i < 1); } if (array[3] == array[2] || array[3] == array[1] || array[3] == array[0]) { i = 0; do { array[3] = zufallszahl.Next(1, 50); i++; } while (i < 1); } else { i = 0; do { array[4] = zufallszahl.Next(1, 50); i++; } while (i < 1); } if (array[4] == array[3] || array[4] == array[2] || array[4] == array[1] || array[4] == array[0]) { i = 0; do { array[4] = zufallszahl.Next(1, 50); i++; } while (i < 1); } else { i = 0; do { array[5] = zufallszahl.Next(1, 50); i++; } while (i < 1); } if (array[5] == array[4] || array[5] == array[3] || array[5] == array[2] || array[5] == array[1] || array[5] == array[0]) { i = 0; do { array[5] = zufallszahl.Next(1, 50); i++; } while (i < 1); } else { i = 0; do { array[6] = zufallszahl.Next(1, 50); i++; } while (i < 1); } if (array[6] == array[5] || array[6] == array[4] || array[6] == array[3] || array[6] == array[2] || array[6] == array[1] || array[6] == array[0]) { i = 0; do { array[6] = zufallszahl.Next(1, 50); i++; } while (i < 1); } Array.Sort (array); Console.WriteLine("Ihre 6 Zahlen aus 1 bis 49 lauten:"); for (i = 0; i < 6; i++) { Console.Write(array[i] + "\t"); } Console.WriteLine("\nund Ihre Zusatzzahl ist die :"+array[6]); Console.ReadLine(); } Ich danke euch schonmal für Antworten ! Gruß Itsjustme Zitieren
flashpixx Geschrieben 31. Januar 2010 Geschrieben 31. Januar 2010 Ich gebe einmal als Idee diesen Pseudocode an: lottozahlen = array[1..6]; lottozahlen[1] = random(1,49); for i=2 to 6 do do lottozahlen[i] = random(1,49); while lottozahlen[i] not in lottozahlen[1..i-1] endfor Zitieren
Itsjustme Geschrieben 31. Januar 2010 Autor Geschrieben 31. Januar 2010 Danke für deine Antowort ! Oha ...... Also wenn ich den Code richtig verstanden habe , dann deklarierst du das Array mit dem name lottozahlen und vergibst die Arraygröße in der 7 zahlen rein passen . Dann packst du in den ersten Index des Arrays schonmal eine zahl generiert aus der methode Random ... Bis jetzt habe ich alles verstanden , nur dannach programmierst du für mich eine völlig neue verschachtelte for schleife ! Aber ich denk mal das sie wie folgt funktionieren soll : for schleife mit der anfangs bedingung durchlaufe von 2 bis 6 fülle bei jedem durchlauf mittels do while schleife das Array mit einer Zahl aus der Methode Random . jedoch bei dem While verlässt es mich , da habe ich keine ahnung was da passiert . Vielleicht kannst du mir ja weiterhelfen , bin noch blutiger anfänger was C# angeht ..... Zitieren
flashpixx Geschrieben 31. Januar 2010 Geschrieben 31. Januar 2010 Bitte noch einmal nachdenken, wie groß das Array ist! Lottzahlen sind 6 Zahlen aus 49, sprich ein Urnenexperiment ohne zurück legen. Das ganze hat hier noch nicht's mit C# zu tun. Es geht nur um den Algorithmus Zitieren
abi2010 Geschrieben 31. Januar 2010 Geschrieben 31. Januar 2010 Folgende Variante dürfte funktionieren int[] lotto = new int[6]; Random random = new Random(); for (int i = 0; i < lotto.Length; i++) { //lotto[i] zufallszahl zuweisen lotto[i] = random.Next(1, 49); //überprüfen, ob die zahl schon vergeben wurde for (int j = 1; j <= i; j++) { //falls die zahl schon vergeben wurde, dann verkleiner i if (lotto[j-1] == lotto[j]) { i--; } } } //array sortieren Array.Sort(lotto); Zitieren
flashpixx Geschrieben 31. Januar 2010 Geschrieben 31. Januar 2010 Das ist etwas unschön, da Du Zählvariable veränderst. Gerade, wenn man hier Schleifeninvariante via Induktionsbeweis zeigen muss, ist das sehr unschön. Es ist von der Struktur einfacher so lange zu würfeln, bis man keine Duplikate mehr hat und dann entsprechend den Index zu inkrementieren Zitieren
abi2010 Geschrieben 31. Januar 2010 Geschrieben 31. Januar 2010 Vielleicht nicht ganz schön, funktioniert aber trotzdem und da das Programm nicht arg umfangreich und die Berechnungen/Schleifendurchläufe nicht sehr lange dauern eine durchaus effektive Methode - imho Zitieren
Itsjustme Geschrieben 1. Februar 2010 Autor Geschrieben 1. Februar 2010 @flashpixx Über die Indexgröße des Arrays habe ich mir schon gedanken gemacht . Habe die 7 gewählt , da ja noch die Zusatzzahl gewürfelt werden muss . Wollte halt nicht noch eine Variable für die Zusatzzahl erstellen und habs dann einfach in das Array gepackt ..... @Abi2010 Danke für deinen Lösungsvorschlag ! Der ist natürlich vom Quellcode her bedeutend kleiner und schneller zu programmieren . Dachte mir schon irgendwie , das man das mit ner Schleife prüfen kann . Bin aber irgendwie nicht drauf gekommen und habs dann mit den If und Else schleifen gelöst . Hatte zudem ja auch keine Vorgabe wie ich auf die Lösung kommen muss .... @flashpixx Was wäre denn ein Induktionsbeweis ? Und was wäre an der Lösung von Abi2010 so falsch ? Nur weil er die zähl Variable der ersten For-Schleife zurück setzt ? Was würde laut Induktionsbeweis für ein Fehler auftreten ? Viele fragen , ich weiss , hab das C# Programmieren erst seit nem halben Jahr auf der Abendschule und bin wissbegierig da mir das programmieren irgendwie Spass macht . Zitieren
flashpixx Geschrieben 1. Februar 2010 Geschrieben 1. Februar 2010 Was wäre denn ein Induktionsbeweis ? Vollständige Induktion ? Wikipedia Und was wäre an der Lösung von Abi2010 so falsch ? Nur weil er die zähl Variable der ersten For-Schleife zurück setzt ? Diese Lösung ist nicht falsch, sie ist eben "nicht sinnvoll". Dies sieht man aus der Algorithmik heraus Was würde laut Induktionsbeweis für ein Fehler auftreten ? Der Beweis wird durch so ein Konstrukt viel schwieriger, da ich eben nicht einfach n->n+1 bzw n->n-1 beweisen kann, was man bei einder Induktion macht. Viele fragen , ich weiss , hab das C# Programmieren erst seit nem halben Jahr auf der Abendschule und bin wissbegierig da mir das programmieren irgendwie Spass macht . Dann gebe ich Dir hier den Rat, dass Du Dir einen guten Stil angewöhnst und Dir sinnvolle und strukturierte Algorithmen überlegst. Das Beispiel von Abi2010 ist eben ein solches Beispiel, das man vermeiden sollte. Bei komplexere Strukturen kann so etwas gerne völlig schief gehen: Man kann leicht erkennen, wenn man die If-Bedingung abändert, dass man Gefahr läuft dass i negativ wird, greifst Du auf den Index -1 zu, wird das einen Fehler produzieren. Man versucht eben gerade Schleifen so zu designen, dass sie terminieren. Ein Zugriff auf den Arrayindex -1 führt zu einem nicht definierten Verhalten des Programms. Man zeigt dies durch das Hoare Kalkül (Hoare-Kalkül ? Wikipedia) bzw durch die Schleifeninvariante (Schleifeninvariante ? Wikipedia). Das sind Formalismen um eben auch zu beweisen, dass eine Schleife immer das macht, was sie soll, d.h. es ist immer definiert in welchem Zustand sie sich befindet. Wie schon gesagt, stell Dir das einfach bei einem sehr großen komplexen Quellcode vor, wenn unter Umständen da mehrere Leute dran arbeiten und man eben solche Konstruke wie sie abi2010 genannt hat, erstellt, dann kann durch eine zweite Änderung das Programm etwas machen, was nicht gewollt ist Zitieren
autschen Geschrieben 1. Februar 2010 Geschrieben 1. Februar 2010 (bearbeitet) also ich würde es mal so machen :schlaf: class Lotto { Random random = new Random(); public void Generator() { int[] lottoZahlen = new int[6]; for (int i = 0; i < 6; i++) { int randomzahl = random.Next(1, 49); for (int j = 0; j <= i; j++) { if (lottoZahlen[j].Equals(randomzahl) == true) { j = 0; randomzahl = random.Next(1, 49); } } lottoZahlen[i] = randomzahl; } Ausgabe(lottoZahlen); } private void Ausgabe(int[] zahlen) { Console.WriteLine("Lottozahlen:"); foreach (int i in zahlen) { Console.WriteLine(i); } Console.WriteLine("Zustazzahl: " + random.Next(1, 49)); Console.Read(); } } Bearbeitet 1. Februar 2010 von autschen Zitieren
flashpixx Geschrieben 1. Februar 2010 Geschrieben 1. Februar 2010 @autschen: Dein "if equals" wird immer true liefern, da Deine Schleife bis <= zum i-ten Element läuft, d.h. Du hast eine Operation mehr als notwendig. Im Fall i == 0 führst Du die Schleife aus, obwohl es nicht notwendig ist. Als zweiter Punkt wird es bei Dir Duplikate geben, denn wenn man auf dem i-ten Element steht, eine Zufallszahl würfelt, dann in der inneren Schleife alle Element von 0 bis i-1 durchläuft und bei dann genau einmal neu würfelt, wenn ein Duplikat auftritt, schließt das nicht aus, dass auch zweimal hintereinander die gleichen Zahlen erscheinen. Somit stimmt der Code nicht entsprechend der Aufgabenstellung. Man muss so lange würfeln, bis kein Duplikat mit den vorhergehenden Elementen auftritt Zitieren
Pointerman Geschrieben 1. Februar 2010 Geschrieben 1. Februar 2010 Kleiner Spass zur Mittagspause: Wenn man nicht jedesmal pruefen will, ob eine Zahl schon verwendet wurde kann man auch eine Liste mit den Zahlen fuellen und dann beim ziehen das entsprechende Element loeschen. Das ist dann wie die Ziehung aus einer richtigen Urne! List<int> verfuegbareNummern = new List<int>(); for(int aktuelleNummer = 1; aktuelleNummer < 50; aktuelleNummer++) { verfuegbareNummern.Add(aktuelleNummer); } Random random = new Random(); Console.WriteLine("Die Lottozahlen:"); for (int ziehung = 0; ziehung < 6; ziehung++) { int position = random.Next(verfuegbareNummern.Count); Console.WriteLine("Lottozahl Nr. " + (ziehung +1).ToString() + " ist die " + verfuegbareNummern[position].ToString()); verfuegbareNummern.RemoveAt(position); } Zitieren
autschen Geschrieben 1. Februar 2010 Geschrieben 1. Februar 2010 (bearbeitet) also mein equals bringt nicht immer true, er durchläuft die bis dato gesetzen werte und prüft diese gegen die random zahl. ist jetzt die nummer vorhanden wird der j wert wieder auf 0 (fehler: muss auf -1) gesetzt und eine neue random zahl generiert welche dann wieder gegen alle bis dato gesetzten zahlen geprüft wird und wenn keine equals ist diese in das array einfügt punkt 2 das <= i dient dazu das der wert i(0) also das erste element auch geprüft wird. in meinen test durchläufen hat es wunderbar funktioniert. Bearbeitet 1. Februar 2010 von autschen Zitieren
Pointerman Geschrieben 1. Februar 2010 Geschrieben 1. Februar 2010 @autschn punkt 2 das <= i dient dazu das der wert i(0) also das erste element auch geprüft wird. in meinen test durchläufen hat es wunderbar funktioniert. Waere nicht ein einfaches < an dieser Stelle richtig? So pruefst Du doch auch das Element i, das ja in diesem Schleifendurchlauf erst gesetzt werden soll, oder? Zitieren
autschen Geschrieben 1. Februar 2010 Geschrieben 1. Februar 2010 (bearbeitet) @autschn Waere nicht ein einfaches < an dieser Stelle richtig? So pruefst Du doch auch das Element i, das ja in diesem Schleifendurchlauf erst gesetzt werden soll, oder? ja du hast recht ein einfaches < geht auch, hab mir das nochmal angeguckt es macht keinen sinn ist aber auch nicht falsch :D. musste ja schnell gehen weil mittagessen hat gewartet :cool::cool: Bearbeitet 1. Februar 2010 von autschen Zitieren
autschen Geschrieben 1. Februar 2010 Geschrieben 1. Februar 2010 ja du hast recht ein einfaches < geht auch, hab mir das nochmal angeguckt es macht keinen sinn ist aber auch nicht falsch :D. hatte ja nur 7 min dann war schon mittagessen angesagt Zitieren
lbm1305 Geschrieben 1. Februar 2010 Geschrieben 1. Februar 2010 Kleiner Spass zur Mittagspause: Wenn man nicht jedesmal pruefen will, ob eine Zahl schon verwendet wurde kann man auch eine Liste mit den Zahlen fuellen und dann beim ziehen das entsprechende Element loeschen. Das ist dann wie die Ziehung aus einer richtigen Urne! List<int> verfuegbareNummern = new List<int>(); for(int aktuelleNummer = 1; aktuelleNummer < 50; aktuelleNummer++) { verfuegbareNummern.Add(aktuelleNummer); } Den Code kann man auch kürzer halten var zahlen = Enumerable.Range(1, 50); // oder List<int> zahlen = Enumerable.Range(1, 50).ToList(); Zitieren
Pointerman Geschrieben 1. Februar 2010 Geschrieben 1. Februar 2010 @lbm1305 Enumerable.Range(...) kannte ich noch nicht. Danke für den Tip! Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.