繁体   English   中英

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

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

我正在尝试使用NetBeans IDE 6.9.1创建Bingo游戏(我是编码方面的菜鸟)。 现在,我被困在尝试创建宾果卡。 对于5x5卡的盒子,我使用了jButton。 我无法在“ B”列中随机分配“ B”宾果球。 我有一个“工作”的代码,用于随机化哪个“ B”球进入哪个“ B” jButton,但是我的方法不适用于我用来输出随机绘制的宾果球的jLabel。 这是我的“随机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)]);

以下是用户选择宾果图案时单击提交按钮时的代码,该卡片将生成(不完整):

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

是的,这是重复性的,并且不是随机的,但是我对数组做了一些研究,因为我在计算机科学课上还没有学到它们,并且得到了:

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

这只是一个测试代码,如您所见,我仍然可以多次获得B1,这不是我想要的宾果卡和随机挑选的宾果球(我还没有开始)的意思。 另外,每当我运行程序时,它都不会打印出最后一行。 我需要在星期三结束前完成此操作:/(这是ISU项目的一个较晚项目,不,我没有晚开始)。 谢谢你的时间。

我希望这并不太远,但是从一包N物品(球)中取出M元素而不重复的最简单方法是简单地将所有元素添加到Listshuffle() ,然后使用subList()获取前M值。

这是执行此操作的通用方法:

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

测试

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

样品输出

[B9, B5, B3, B2, B15]

更新

好的,为了便于教学, List有点类似于数组,但是功能更强大。 它包含一个值序列(如数组),并且值从0开始索引,也像数组一样。

与数组不同,在数组中您使用arr.length获得长度,对于列表,您调用list.size() 而不是使用arr[2]检索值,而是调用list.get(2)

可以使用list.set(2, 7)而不是使用arr[2] = 7分配值list.set(2, 7)但这并不常见。 这是因为与使用new String[5]分配的数组分配5个值的固定大小的数组不同,使用new ArrayList()分配了列表,并且在调用add() new ArrayList() ,列表的大小将根据需要add() ,就像上面的方法一样。

在简短介绍之后,下面是您使用上述方法的方式:

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

如果要获取随机数,可以使用Math.random()Random ,这与您的问题无关。 您的问题就是您要显示的内容。 一种方法是从特殊的最大数中获得随机数,并且最大数不变。 我想这就是您现在使用的。 另一种方法,当您从特殊的最大数中获得一个随机数,然后删除该随机数时,请确保将使用每个数字(从最小到最大)。 Java有一个Collections.java工具,该工具具有shuffle功能,可以使整个列表随机化。 以下是适合您的示例测试代码。 如果您希望每个数字(从最小到最大)均等地出现,则可以使用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);
        }
    }
}

请记住random.nextInt(value)返回0到(value-1)。 希望对您有所帮助。

您必须知道Math.random()给出一个介于0和1之间的数字。

它永远不会给出1。

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

请注意下限逻辑,它使您永远不会获得索引2。

不要尝试使用Math.random,您将不会获得均匀的分布。 使用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)
}

然后,您将以随机顺序获得商品清单。 如果您需要真正的随机性,那么必须使用SecureRandom并不是真正的随机性,只是伪随机性。 我确信这可能是使用Java 8流功能上实现此目的的一种更简单的方法,但是我还没有太多时间来弄乱它们,因此,如果答案是老式的,对不起。

暂无
暂无

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

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