创建一个彩票机

时间:2017-05-04 13:54:38

标签: java

我正在创建一个项目的困难,该项目正在创建一个彩票机,在1到42之间随机打印6个数字,其中没有2个数字是相同的。用户还必须插入6个数字。如果任何数字与计算机随机选择的数字相同,则计算机必须打印它。如果没有,电脑打印你就是这样一个失败者。现在,问题是我不确定如何确保没有2个随机选择的数字是相同的。如果数字小于1,大于42或等于插入的前一个数字,程序也应该要求不同的数字,并扫描它。 (用户不能输入2个相同的数字) PS:我只是一个知道for循环while循环的初学者和if语句所以如果答案非常简单和基本,我会喜欢它。请检查我的代码并告诉我是否有任何不起作用或不合逻辑。提前谢谢

 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");
       }
   }
}

6 个答案:

答案 0 :(得分:3)

The Fisher Yates Shuffle正迅速成为我对Stackoverflow上所有内容的回答。

您应该执行以下操作:

  • 按升序创建一个包含42个数字的数组。该数组的索引在0到41之间。
  • 生成随机数r0,其中0 <= r0 < 42
  • 将索引0处的数字与索引r0处的数字交换。
  • 生成随机数r1,其中1 <= r1 < 42
  • 将索引1处的数字与索引r1处的数字交换。
  • 生成随机数r2,其中2 <= r2 < 42
  • 将索引2处的数字与索引r2处的数字交换。

等等,直到您在索引5处交换了数字。显然,将上述步骤放在循环中是微不足道的。另请注意,将数字与自身交换不是错误。

数组中的前六个数字(索引0到5)是选定的彩票号码。

可以推广该算法以从m个对象中选择任何n个唯一项。例如,拥有52个项目的数组并通过所有52项是一个方便的方式来模拟洗牌一堆卡。

这里有一些实现算法的代码(我没有编译或测试它,所以可能会出错)

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 :(得分:0)

我修好了。当你找到匹配的数字时你必须将你的j重置为0而你不能从0开始,因为那时你将总是比较索引0处的相同数字。

P.S。学习循环

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");
       }
   }
}

答案 2 :(得分:0)

最简单,最有效的方法是将可能的数字放入List中,然后从列表中删除一个随机元素,直到您拥有所需数量:

 // 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());
 }

你可以用数组做类似的事情,但它更复杂,因为你必须编写自己的数组List.remove()。也许你在学习中还没有遇到List - 但是如果你想要一个简单的解决方案,你需要使用适当的工具,并且列表比数组更容易使用。

或者,如果你想让自己的生活变得更加艰难,你可以使用数组。

// 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];
}

每次我们输入一个数字时,我们会将availableSize减少一个,并覆盖我们从available获取的数字,其中未使用的数字位于数字左侧的顶部。例如,在开始时(让我们选择6个候选人而不是42个):

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]

...但6中的第二个available无关紧要,因为下次我们只会从前5个元素中选择。

答案 3 :(得分:0)

有两种不同的方法可以解决这个问题。在这两种情况下,您需要交易使用更多内存或执行更多计算。

第一个使用更多内存但计算效率

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--;
}

第二种方法在计算上更昂贵但存储效率

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;
    }
}

第一个创建一个唯一编号列表并从此列表中绘制。之后,从列表中删除所绘制的数字。第二种方法是绘制随机数并检查所绘制的数字是否已经存在,如果是,则将其丢弃。

答案 4 :(得分:0)

为了更容易看到并使用现代Java8流,您可以使用Collections API来更清楚地说明:

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;
}

////其余代码(也重写)

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);
    }

}

答案 5 :(得分:-1)

来自Creating random numbers with no duplicates

的回答

代码(适合您)是:

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