2017-05-04 1 views
1

Ich habe Schwierigkeiten mit einem Projekt, das eine Lotterie-Maschine erstellt, die 6 Zahlen zwischen 1 und 42 nach dem Zufallsprinzip druckt, wo keine 2 Zahlen gleich sind. Der Benutzer muss auch 6 Nummern eingeben. Wenn eine Nummer mit der zufällig vom Computer gewählten übereinstimmt, muss der Computer sie ausdrucken. Wenn nicht, druckt der Computer Sie sind ein solcher Verlierer. Nun, das Problem ist, ich bin mir nicht sicher, wie man sicherstellen kann, dass keine 2 zufällig ausgewählten Nummern gleich sind. Das Programm sollte auch nach einer anderen Nummer fragen, wenn eine Nummer kleiner als 1, größer als 42 oder gleich einer vorherigen Nummer eingefügt wird, und es scannen. (Benutzer kann nicht 2 identische Nummern eingeben) PS: Ich bin nur ein Anfänger, der die for-Schleife While-Schleife kennt und wenn ich so sagen würde, würde ich es lieben, wenn die Antworten sehr einfach und grundlegend wären. Bitte überprüfen Sie meinen Code und sagen Sie mir, ob etwas nicht funktioniert oder unlogisch ist. Vielen Dank im VorausErstellen einer Lotterie-Maschine

import java.util.Scanner; 
import java.util.Random; 

public class LotoMachine { 

public static void main(String[] args) { 

    System.out.println("Please enter 6 numbers between 1 and 42."); 
    Scanner scan = new Scanner(System.in); 

    int[] marks = new int[6]; 
    Random ran = new Random(); 
    int[] x = new int[6]; 
    boolean winner = false; 

    for (int i = 0; i < 6; i++) { 
     marks[i] = scan.nextInt(); 
    } 
    for (int j = 0; j < 6; j++) { 
     x[j] = ran.nextInt(42) + 1; 
     for (int y = 0; y < j; y++) { 
      if (x[j] == x[y]) { 
       x[j] = ran.nextInt(42) + 1; 
       j=0; 
      } 
     } 
    } 

    for (int m = 0; m < 6; m++) { 
     System.out.println(x[m]); 
    } 
    for (int i = 0; i < 6; i++) { 
     for (int j = 0; j < 6; j++) { 
      if (marks[i] == x[j]) { 
       winner = true; 
       System.out.println("Number(s) that matched: " + marks[i]); 
      } 
     } 
    } 
    if (winner != true) { 
     System.out.println("You are such a loser"); 
     } 
    } 
} 
+0

ist, was ich versuchte, aber ich bin mir nicht sicher, ob es für (int j = 0 arbeitet; j <6; j ++) { x [j] = ran.nextInt (42) + 1 ; für (int y = 0; y

+2

Verwenden Sie eine while-Anweisung und erstellen Sie eine Zufallszahl, bis keine Übereinstimmung im Zufallszahlenfeld vorhanden ist. – brad

+1

Mögliches Duplikat von [Erstellen von Zufallszahlen ohne Duplikate] (http: // stackoverflow.com/questions/4040001/creating-random-numbers-with-no-duplicates) –

Antwort

-1

Antwort von Creating random numbers with no duplicates

Der Code (für Sie) ist:

Random rng = new Random(); // Ideally just create one instance globally 
// Note: use LinkedHashSet to maintain insertion order 
Set<Integer> generated = new LinkedHashSet<Integer>(); 
while (generated.size() < 6) //repeat as long as generated.size() < 6 -> means you dont have 6 unique integers 
{ 
    Integer next = rng.nextInt(42) + 1; 
    // As we're adding to a set, this will automatically do a containment  check 
generated.add(next); 
} 
int[] lottery_numbers = generated.toArray(); 
//Do want you want to do with the 6 lottery numbers 
+0

Ich bin noch ein Anfänger, also habe ich noch nicht gelernt, while do it while does und gibt es eine Alternative –

+0

** while ** (__die Bedingung hier ist wahr__) {__do Was ist hier drin?}. Wirklich einfach – qry

+0

oh okay danke @LikeBlender –

3

The Fisher Yates Shuffle wird schnell meine goto Antwort für alles auf Stackoverflow.

Sie sollten Folgendes tun:

  • einen Array mit den in aufsteigender Reihenfolge in ihm 42 Zahlen erstellen. Das Array wird indiziert zwischen 0 und 41.
  • Generieren einer Zufallszahl r0 wo 0 <= r0 < 42
  • Swap die Anzahl an Index 0 mit der Anzahl an Index r0.
  • Generieren Sie eine Zufallszahl r1, wobei 1 <= r1 < 42
  • tauschen Sie die Nummer bei Index 1 mit der Nummer bei Index r1.
  • Generieren Sie eine Zufallszahl r2 2 <= r2 < 42
  • vertauschen Sie die Nummer bei Index 2 mit der Nummer bei Index r2.

und so weiter, bis Sie die Zahl bei Index 5 vertauscht haben. Offensichtlich ist es trivial, die obigen Schritte in eine Schleife zu setzen. Beachten Sie auch, dass es kein Fehler ist, eine Zahl mit sich selbst zu tauschen.

Die ersten sechs Zahlen in Ihrem Array (Indizes 0 bis 5) sind die ausgewählten Lottozahlen.

Der Algorithmus kann verallgemeinert werden, um beliebige n eindeutige Objekte aus m Objekten auszuwählen. Wenn Sie zum Beispiel ein Array von 52 Gegenständen haben und alle 52 durchlaufen, ist das eine praktische Möglichkeit, ein Kartenspiel zu mischen.

Hier einige Code, um den Algorithmus zu implementieren (ich habe es nicht kompiliert oder getestet, so könnte es Fehler sein

Random random = new java.util.Random(); 

int numbers[] = new int[42]; 

// create the initial array 
for (int i = 0 ; i < 42 ; ++i) 
{ 
    numbers[i] = i + 1; 
} 

// shuffle 
for (int i = 0 ; i < 6 ; ++i) 
{ 
    int ri = random.nextInt(42 - i) + i; // generates a random index between i and 42 
    int tmp = numbers[ri]; 
    numbers[ri] = numbers[i]; 
    numbers[i] = tmp; 
} 

// your six lottery numbers are in numbers[0] to numbers[5] 
+1

_Obviously ist es trivial, die oben genannten Schritte in eine Schleife zu setzen _ .... Ich denke nicht jemand, der gerade mit Java anfängt, würde zustimmen –

+0

@RobinTopper Nach dem Codefragment in der Frage zu urteilen, würde ich sagen, dass "user7963567" bereits mit dem Konzept einer Schleife vertraut ist. Auch für sechs Nummern können Sie es abgerollt lassen. – JeremyP

0

Da ist es ich festgelegt. Sie hatten Ihre j auf 0 zurückgesetzt, wenn Sie matching numbers finden UND Sie können nicht von 0 in beiden für's beginnen, weil Sie dann immer die gleichen Zahlen bei Index 0 vergleichen werden.

PSErfahren Sie while-Schleife

import java.util.Scanner; 
 
import java.util.Random; 
 

 
public class LotoMachine { 
 

 
public static void main(String[] args) { 
 

 
    System.out.println("Please enter 6 numbers between 1 and 42."); 
 
    Scanner scan = new Scanner(System.in); 
 

 
    int[] marks = new int[6]; 
 
    Random ran = new Random(); 
 
    int[] x = new int[6]; 
 
    boolean winner = false; 
 

 
    for (int i = 0; i < 6; i++) { 
 
     marks[i] = scan.nextInt(); 
 
    } 
 
    for (int j = 0; j < 6; j++) { 
 
     x[j] = ran.nextInt(42) + 1; 
 
     for (int y = 0; y < j; y++) { 
 
      if (x[j] == x[y]) { 
 
       x[j] = ran.nextInt(42) + 1; 
 
       j=0; 
 
      } 
 
     } 
 
    } 
 

 
    for (int m = 0; m < 6; m++) { 
 
     System.out.println(x[m]); 
 
    } 
 
    for (int i = 0; i < 6; i++) { 
 
     for (int j = 0; j < 6; j++) { 
 
      if (marks[i] == x[j]) { 
 
       winner = true; 
 
       System.out.println("Number(s) that matched: " + marks[i]); 
 
      } 
 
     } 
 
    } 
 
    if (winner != true) { 
 
     System.out.println("You are such a loser"); 
 
     } 
 
    } 
 
}

+0

danke viel btw können Sie erklären, was Sie ein bisschen mehr getan haben bitte –

+0

BTW danke für Ihre Antwort denken Sie, dies ist eine einfache Möglichkeit, mein Ziel anstelle der Fisher Yates Shuffle zu erreichen und wenn ich das Mischen verwenden würde, wie würde ich Schreibe es in Code @ JeremyP –

+0

Wenn Sie eine doppelte Nummer finden, müssen Sie die for-Schleife von Anfang an zurücksetzen, weil eine neue Nummer in den zuvor hinzugefügten enthalten sein könnte. –

0

Die einfachste und effizienteste Sache ist, die möglichen Zahlen in einer Liste zu setzen, dann ein zufälliges Element aus der Liste entfernen, bis Sie so viele wie Sie benötigen:

// create a list containing 1 .. 42 
List<Integer> available = new ArrayList<>(); 
for(int i=1; i<=42; i++) { 
    available.add(i); 
} 

// pull 6 numbers from `available` at random 
List<Integer> picks = new ArrayList<>(); 
for(int i=0; i<6; i++) { 
    picks.add(available.remove(random.nextInt(available.size()); 
} 

Sie können etwas ähnliches mit Arrays tun, aber es ist komplizierter, weil Sie Ihr eigenes Array-Äquivalent von List.remove() schreiben müssten. Vielleicht sind Sie in Ihren Studien noch nicht auf List gestoßen - aber wenn Sie eine einfache Lösung wünschen, müssen Sie die entsprechenden Tools verwenden, und Listen sind einfacher zu verwenden als Arrays.


Alternativ können Sie nur Arrays verwenden, wenn Sie das Leben etwas schwerer für sich selbst machen wollen.

// create an array containing 1..42 
int[] available = new int[42]; 
for(int i=0; i<42;i++) { 
    available[i] = i+1; 
} 

// pull out 6 numbers 
int[] picks = new int[6]; 
int availableSize = 6; 
for(i=0; i<6;i++) { 
    int r = random.nextInt(availableSize); 
    // grab the pick 
    picks[i] = available[r]; 
    // move an unused number over the picked one 
    availableSize--; 
    available[r] = available[availableSize]; 
} 

Jedes Mal, wenn wir eine Reihe nehmen, reduzieren wir availableSize nach der anderen, und überschreiben Sie die Zahl, die wir von available mit einem nicht verwendete eine von oben genommen haben, was die Zahlen übrig geblieben ist. So zum Beispiel am Anfang (lassen Sie sich mit 6 Kandidaten statt 42 gehen):

available == [1,2,3,4,5,6] 
availableSize == 6 
r = 3 // for example 
picks[0] becomes available[3] == 3 
availableSize becomes 5 
available becomes [1,2,6,4,5,6] 

... aber die zweiten 6 in available ist irrelevant, denn beim nächsten Mal werden wir nur von den ersten Pick 5 Elemente.

+0

Es ist ein Fehler meines, dass Lehrer scheinen, dass Schüler Arrays vor Collections verwenden. Es ist wichtig, Arrays zu verstehen, aber ich denke, es ist besser, sich zuerst daran zu gewöhnen, Konstrukte auf APIs höherer Ebenen zu programmieren. – slim

+0

ist es möglich, es ohne eine Liste zu tun, weil du Recht hast Ich habe es noch nie zuvor gesehen –

+0

Es ist möglich - siehe oben - aber IMO sollten Sie List vor Arrays lernen. – slim

0

Es gibt zwei verschiedene Möglichkeiten, wie Sie das lösen können. In beiden Fällen müssen Sie entweder mit mehr Speicher arbeiten oder mehr Berechnungen durchführen.

Die erste verwendet mehr Speicher, ist aber rechnerisch effizient

int[] numbers = new int[42]; 
int len = 42; 
for (int i = 0; i < 42; i++) { 
    numbers[i] = i + 1; 
} 

for (int i = 0; i < 6; i++) { 
    int pos = rng.nextInt(len); 
    x[i] = numbers[pos]; 

    for (int j = pos + 1; j < len; j++) { 
     numbers[j - 1] = numbers[j]; 
    } 
    pos--; 
} 

Der zweite Ansatz ist rechnerisch teurer, aber speichereffiziente

int pos = 0; 
while (pos < 6) { 
    int number = rng.nextInt(42) + 1; 
    boolean duplicate = false; 
    for (int i = 0; i < pos; i++) { 
     if (x[i] == number) { 
      duplicate = true; 
     } 
    } 

    if (!duplicate) { 
     x[pos++] = number; 
    } 
} 

Die erste eine Liste der eindeutigen Nummer erzeugt und zieht aus diese Liste. Danach wird die gezeichnete Nummer aus der Liste entfernt. der zweite Ansatz zeichnet Zufallszahlen und prüft, ob die gezeichnete Zahl bereits existiert, wenn sie verworfen wird.

0

Um ein bisschen leichter für das Auge und den Einsatz moderner Java8 ströme Sie die Sammlungen API ein bisschen mehr klar sein, um shuflle verwenden:

private static Set<Integer> generateXuniqueNumbersFromRange(int unique, int start, int end) { 
    List<Integer> availableLotteryNumbers = IntStream.rangeClosed(start, end).boxed().collect(Collectors.toList()); 
    Collections.shuffle(availableLotteryNumbers); 
    Set<Integer> lotteryNumbers = availableLotteryNumbers.stream().limit(unique) 
      .collect(Collectors.toCollection(TreeSet::new)); 
    return lotteryNumbers; 
} 

//// Rest des Codes (auch Diese neu geschrieben)

public static void main(String[] args) { 
    Set<Integer> lotteryNumbers = generateXuniqueNumbersFromRange(6, 1, 42); 

    Set<Integer> userSelection = new TreeSet<>(); 

    try (Scanner scan = new Scanner(System.in)) { 
     while (userSelection.size() < 6) { 
      int nextInt = scan.nextInt(); 
      if (nextInt <= 42 && nextInt >= 1) { 
       userSelection.add(nextInt); 
      } else { 
       System.out.println("Select between 1 - 42"); 
      } 
     } 
    } 

    System.out.println("You had these numbers " + userSelection); 
    System.out.println("The lottery selected " + lotteryNumbers); 
    userSelection.retainAll(lotteryNumbers); 

    if (userSelection.isEmpty()) { 
     System.out.println("You are such a loser"); 
    } else { 
     System.out.println("You had " + userSelection.size() + " correct ones " + userSelection); 
    } 

}