【问题标题】:How to display randomly selected strings from an array in java without repetitions如何在java中显示从数组中随机选择的字符串而不重复
【发布时间】:2016-06-21 02:58:46
【问题描述】:

我正在尝试使用 NetBeans IDE 6.9.1 创建一个宾果游戏(我是个编码新手)。现在我一直在尝试创建宾果卡。对于 5x5 卡的盒子,我使用了 jButtons。我不能随机排列“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 项目,不,我没有迟到)。感谢您的宝贵时间。

【问题讨论】:

标签: java arrays random


【解决方案1】:

我希望这不会超出您的位置,但是从N 项目(球)袋中提取M 元素而不重复的最简单方法是将所有元素添加到@ 987654321@ 和 shuffle() 它,然后使用 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 分配值,但这并不常见。这是因为,与使用new String[5] 分配的数组不同,它分配5 个值的固定大小数组,列表使用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));

【讨论】:

  • 这行代码出现错误:List&lt;String&gt; balls = new ArrayList&lt;&gt;(); 因为 -source 1.6 不支持菱形运算符,我必须使用 -source 7 或更高版本。我尝试下载 Java JDK 7,但它没有显示在“源/二进制格式”下的组合框中。我的老师告诉我们不要更新 NetBeans,因为新版本更难使用。
  • @Michael 所以只需添加类型:new ArrayList&lt;String&gt;()
  • 谢谢,但我现在的错误是什么:private static List&lt;String&gt; draw(String ballPrefix, int noOfBalls, int noToDraw) { List&lt;String&gt; balls = new ArrayList&lt;String&gt;(); noOfBalls = 15; noToDraw = 5; ballPrefix = "B"; for (int ballNo = 1; ballNo &lt;= noOfBalls; ballNo++) { balls.add(ballPrefix + ballNo); } Collections.shuffle(balls); return balls.subList(0, noToDraw); System.out.println(draw(ballPrefix, noOfBalls, noToDraw)); }
  • 为什么将println() 语句添加到draw() 方法中?去掉它。您是否明白 draw() 方法必须在 some 类中,即使我没有显示类声明?如果是这样,你能理解println() 语句必须在 some 方法中,它可以调用 this 方法,即使我没有显示该方法所在的位置测试语句应该是,例如main()?
  • 我现在已经修正了我的愚蠢错误,但是如何在 jButtons 中显示(draw("B", 15, 5))
【解决方案2】:

如果你想得到一个随机数,你可以使用Math.random()Random,这与你的问题无关。你的问题就是你想要展示的。一种方法是从特殊的 Max num 中随机获取,并且 Max 不会改变。我想这就是你现在使用的。另一种方式,当您从特殊的 Max num 中获取随机数,然后删除随机数时,确保将使用每个数字(从 Min 到 Max)。 Java有一个Collections.java工具,里面有shuffle功能,可以让整个列表随机化。下面是为您提供的示例测试代码。如果您希望每个 num(从 Min 到 Max)以相同的速率输出,您可以使用 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)return 0 to (value - 1)。希望能帮到你。

【讨论】:

    【解决方案3】:

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

    它永远不会给出 1。

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

    注意地板的逻辑,它让你永远不会得到索引 2。

    【讨论】:

    • 为了不重复,看一下while循环或List类——你会在后面学习。
    【解决方案4】:

    不要尝试使用 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 流在功能上执行此操作的一种更简单的方法,但是如果答案是老式的,我没有太多时间来处理它们,所以很抱歉。

    【讨论】:

      猜你喜欢
      • 2014-03-10
      • 1970-01-01
      • 2016-02-01
      • 1970-01-01
      • 2019-04-01
      • 2011-11-13
      • 2019-01-28
      • 1970-01-01
      相关资源
      最近更新 更多