简体   繁体   English

如何在Java中不重复显示数组中随机选择的字符串

[英]How to display randomly selected strings from an array in java without repetitions

I'm trying to create a Bingo game using NetBeans IDE 6.9.1 (I'm a noob at coding). 我正在尝试使用NetBeans IDE 6.9.1创建Bingo游戏(我是编码方面的菜鸟)。 Right now I'm stuck at trying to create the bingo card. 现在,我被困在尝试创建宾果卡。 For the 5x5 card's boxes I used jButtons. 对于5x5卡的盒子,我使用了jButton。 I can't randomize the "B" bingo balls down the "B" column. 我无法在“ B”列中随机分配“ B”宾果球。 I have a code that "works" for randomizing which "B" ball goes in which "B" jButton, but my method will not work for the jLabel I'm using to output the randomly drawn bingo ball. 我有一个“工作”的代码,用于随机化哪个“ B”球进入哪个“ B” jButton,但是我的方法不适用于我用来输出随机绘制的宾果球的jLabel。 Here's my "random B-ball code:" 这是我的“随机B球代码”:

String[] Bball1 = {"B5", "B6", "B11"};
String Brandom1 = (Bball1[new Random().nextInt(Bball1.length)]);
String[] Bball2 = {"B1", "B8", "B15"};
String Brandom2 = (Bball2[new Random().nextInt(Bball2.length)]);
String[] Bball3 = {"B3", "B10", "B13"};
String Brandom3 = (Bball3[new Random().nextInt(Bball3.length)]);
String[] Bball4 = {"B2", "B9", "B14"};
String Brandom4 = (Bball4[new Random().nextInt(Bball4.length)]);
String[] Bball5 = {"B4", "B7", "B12"};
String Brandom5 = (Bball5[new Random().nextInt(Bball5.length)]);

Here is the code for when the user clicks the submit button when they pick a bingo pattern and the card would be generated (incomplete): 以下是用户选择宾果图案时单击提交按钮时的代码,该卡片将生成(不完整):

    btnSubmit.setEnabled(false);
    cboPattern.setEnabled(false);
    btn1B.setText(Brandom1);
    btn2B.setText(Brandom2);
    btn3B.setText(Brandom3);
    btn4B.setText(Brandom4);
    btn5B.setText(Brandom5);

Yes, this is repetitive, and not overly random, but I did some research on Arrays, as I have not learned them in my Computer Science class, and got this: 是的,这是重复性的,并且不是随机的,但是我对数组做了一些研究,因为我在计算机科学课上还没有学到它们,并且得到了:

    public static void main(String[] Bballs) {
    String[] Bball;
    Bball = new String[2];
    Bball[0] = "B1";
    Bball[1] = "B2";
    Bball[2] = "B3";

    int num = (int) (Math.random() * 2);
    System.out.println(Bball[num]);
}

This is just a test code, and as you can see I could still get B1 more than one time which isn't what I want for the bingo card and the randomly picked bingo balls (which I haven't started yet). 这只是一个测试代码,如您所见,我仍然可以多次获得B1,这不是我想要的宾果卡和随机挑选的宾果球(我还没有开始)的意思。 Plus, whenever I run my program it doesn't print out the last line. 另外,每当我运行程序时,它都不会打印出最后一行。 I need this done by the end of Wednesday :/ (It's a late ISU project, and no I did not start it late). 我需要在星期三结束前完成此操作:/(这是ISU项目的一个较晚项目,不,我没有晚开始)。 Thanks for your time. 谢谢你的时间。

I hope this is not too far ahead of where you are, but the easiest way to pull M elements from a bag of N items (balls) without repetition, is to simply add all the elements to a List and shuffle() it, then take the first M values using subList() . 我希望这并不太远,但是从一包N物品(球)中取出M元素而不重复的最简单方法是简单地将所有元素添加到Listshuffle() ,然后使用subList()获取前M值。

Here is a generic method for doing that: 这是执行此操作的通用方法:

private static List<String> draw(String ballPrefix, int noOfBalls, int noToDraw) {
    List<String> balls = new ArrayList<>();
    for (int ballNo = 1; ballNo <= noOfBalls; ballNo++)
        balls.add(ballPrefix + ballNo);
    Collections.shuffle(balls);
    return balls.subList(0, noToDraw);
}

Test 测试

System.out.println(draw("B", 15, 5));

Sample output 样品输出

[B9, B5, B3, B2, B15]

UPDATE 更新

Ok, in the interest of teaching a bit, a List is somewhat similar to an array, but much more powerful. 好的,为了便于教学, List有点类似于数组,但是功能更强大。 It contains a sequence of values, like an array, and the values are indexed starting at 0 , also like an array. 它包含一个值序列(如数组),并且值从0开始索引,也像数组一样。

Unlike an array, where you get the length using arr.length , for a list you call list.size() . 与数组不同,在数组中您使用arr.length获得长度,对于列表,您调用list.size() Instead of retrieving a value using arr[2] , you call list.get(2) . 而不是使用arr[2]检索值,而是调用list.get(2)

Instead of assigning a value using arr[2] = 7 , you can call list.set(2, 7) but that is unusual. 可以使用list.set(2, 7)而不是使用arr[2] = 7分配值list.set(2, 7)但这并不常见。 This is because, unlike an array that is allocated using new String[5] , which allocates a fixed-size array of 5 values, a list is allocated using new ArrayList() , and it will grow in size as needed when calling add() , like the method above does. 这是因为与使用new String[5]分配的数组分配5个值的固定大小的数组不同,使用new ArrayList()分配了列表,并且在调用add() new ArrayList() ,列表的大小将根据需要add() ,就像上面的方法一样。

After that super short introduction, here is how you use the method above: 在简短介绍之后,下面是您使用上述方法的方式:

List<String> balls = draw("B", 15, 5);
btn1B.setText(balls.get(0));
btn2B.setText(balls.get(1));
btn3B.setText(balls.get(2));
btn4B.setText(balls.get(3));
btn5B.setText(balls.get(4));

If you want to get a random number, you can use Math.random() or Random , which don't matter your problem. 如果要获取随机数,可以使用Math.random()Random ,这与您的问题无关。 Your problem is what you want to show. 您的问题就是您要显示的内容。 One way is get random from a special Max num, and the Max is not changed. 一种方法是从特殊的最大数中获得随机数,并且最大数不变。 I guess this is what you now use. 我想这就是您现在使用的。 Another way, when you get a random from special Max num ,and then remove the random, ensure every number(from Min to Max) will be used. 另一种方法,当您从特殊的最大数中获得一个随机数,然后删除该随机数时,请确保将使用每个数字(从最小到最大)。 Java has a Collections.java tool, which has shuffle function, it can make the whole list random. Java有一个Collections.java工具,该工具具有shuffle功能,可以使整个列表随机化。 Below is example test code for you. 以下是适合您的示例测试代码。 If you want every num(from Min to Max) come out with equal rate, you can use averageRandom_1 or averageRandom_2 . 如果您希望每个数字(从最小到最大)均等地出现,则可以使用averageRandom_1averageRandom_2

 import java.util.*;
public class Main {

    public static void main(String[] args) {
        System.out.println("Hello World!");
        String[] src = new String[]{"B1", "B2", "B3", "B4", "B5"};
        List<String> srcList = Arrays.asList(src);

   /*     for(int i = 0; i < srcList.size(); i++){
            System.out.print(" random = " + getRandom_2(0, srcList.size()));
        }*/

        averageRandom_2(srcList);
    }

 /**
 * @param min
 * @param max
 * @return [min, max), note it can't return max
 */
public static int getRandom_1(int min, int max){
    return (int)(min + Math.random()*(max-min));
}

/**
 * @param min
 * @param max
 * @return [min, max), note it can't return max
 */
public static int getRandom_2(int min, int max){
    Random random = new Random();
    return random.nextInt(max-min) + min;
}

    public static void averageRandom_1(List<String> data){
        List<String> dataCopy = new ArrayList<>();
        dataCopy.addAll(data);
        Collections.shuffle(dataCopy);
        for(String item : dataCopy){
            System.out.println("--" + item + "--");
        }
    }

    public static void averageRandom_2(List<String> data){
        List<String> dataCopy = new ArrayList<String>(data);
        while(dataCopy.size() > 0) {
            int random = getRandom_2(0, dataCopy.size());
            System.out.println("random = " + random + "--" + dataCopy.get(random) + "--");
            dataCopy.remove(random);
        }
    }
}

Please remember random.nextInt(value) return 0 to (value - 1). 请记住random.nextInt(value)返回0到(value-1)。 Hope to help you. 希望对您有所帮助。

You have to know that Math.random() gives a number within 0 and 1. 您必须知道Math.random()给出一个介于0和1之间的数字。

It never gives 1. 它永远不会给出1。

0 < Math.random() < 1
0 < Math.random() * 2 < 2
0 <= (int)(Math.random() * 2) <= 1

Notice the flooring logic, it makes you never get index 2. 请注意下限逻辑,它使您永远不会获得索引2。

Don't try to use Math.random you wont get an even distribution. 不要尝试使用Math.random,您将不会获得均匀的分布。 Using List and Random.nextInt(int) you get a fairly simple solution like so. 使用List和Random.nextInt(int),您将获得一个非常简单的解决方案,如下所示。

Random rand = new Random();
List<String> inRandomOrder = new ArrayList<>();
List<String> items = new ArrayList<>();
items.add("blah1");
items.add("blah2");
items.add("blah3");

while (!items.isEmpty()) {
    String removed = items.remove(rand.nextInt(items.size()));
    inRandomOrder.add(removed)
}

Then you have a list of your items in some random order. 然后,您将以随机顺序获得商品清单。 It's not really random is only pseudo random if you needed truly random you would have to use SecureRandom. 如果您需要真正的随机性,那么必须使用SecureRandom并不是真正的随机性,只是伪随机性。 I am sure this is probably an easier way to do this functionally with Java 8 streams, but I haven't had a ton of time to mess with them so sorry if the answer is old fashioned. 我确信这可能是使用Java 8流功能上实现此目的的一种更简单的方法,但是我还没有太多时间来弄乱它们,因此,如果答案是老式的,对不起。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM