我正在创建一个项目的困难,该项目正在创建一个彩票机,在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");
}
}
}
答案 0 :(得分:3)
The Fisher Yates Shuffle正迅速成为我对Stackoverflow上所有内容的回答。
您应该执行以下操作:
0 <= r0 < 42
1 <= r1 < 42
2 <= r2 < 42
等等,直到您在索引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