【问题标题】:Generate Random Number Array and Replace Duplicates生成随机数数组并替换重复项
【发布时间】:2015-09-17 22:21:30
【问题描述】:

我正在生成一个 1-54 范围内的 6 个整数数组(类似于乐透号码)。但是,当尝试检测重复项时,我的代码没有执行。如果我的条件逻辑会捕获重复项,我尝试通过简单地打印“WE HAVE FOUND A DUPLICATE”来进行调试。当然,它不会打印所需的输出:

18-33-39-41-41-45

我想检测重复项,以便生成另一个不等于发现的重复项的随机数。我不想仅仅为了获得另一个数字而增加/减少副本的值,我想实际生成另一个不等于副本的 1&54 之间的值。

这是我的代码:

public class Main {

    public static void main(String[] args) {

        Random rand = new Random();
        int[] luckyArray = new int[6];

        //build array
        for (int i = 0; i < luckyArray.length; i++) {

            int luckyNumber = rand.nextInt(54) + 1;
            luckyArray[i] = luckyNumber;
        }
        //detect duplicates in the array
        for (int i = 0; i < luckyArray.length; i++) {
            if (i > 0 && luckyArray[i] == luckyArray[i - 1]) {
                System.out.print("WE HAVE FOUND A DUPLICATE!");
                /* while (luckyArray[i - 1] == luckyArray[i]) {
                    luckyArray[i] = rand.nextInt(54) + 1;
                }*/
            }
        }
        //sort the array before printing
        Arrays.sort(luckyArray);
        for (int t = 0; t < luckyArray.length; t++) {

            if (t != 5) {
                System.out.print(luckyArray[t] + "-");
            } else System.out.print(luckyArray[t]);
        }
    }
}

我希望将当前索引 [i] 与其之前的 [i-1] 进行比较,如果/当它们相等时,为当前索引生成一个新值。

提前致谢!

【问题讨论】:

标签: java arrays random int


【解决方案1】:

我会(个人)在这里依赖 Set 的属性来确保您根本不会保留重复项 - 您甚至不必检查是否有欺骗性:

    Random rand = new Random();
    int numNumsToGenerate = 6;
    Set<Integer> luckySet = new HashSet<Integer>();

    //build set
    while (luckySet.size() < numNumsToGenerate) {
        luckySet.add(rand.nextInt(54) + 1);
    }

一旦您建立了您的集合,您就可以通过使用您的Set 的内容创建一个新的List 来对它们进行排序:

//sort the array before printing
List<Integer> luckyList = new ArrayList<Integer>(luckySet);
Collections.sort(luckyList);

【讨论】:

  • 这是您最好的选择。我只是想建议这个!
  • 请注意,将集合的容量设置为 numNumsToGenerate 是个坏主意。它太小而不能包含 6 个数字,因此会迫使集合重新散列。您至少需要 8 次才能避免重新散列。在这里无关紧要,但通常使用预期大小作为容量不是您应该做的事情。
  • @JBNizet 你能详细说明一下吗?当我给它的初始大小为 6 时,为什么包含 6 个数字会太小?
  • @JonathanScialpi 这当然是可能的(也是一个很好的方法),他只是在评论提供建议的容量/负载系数的效率。
  • @JonathanScialpi 我的建议是忽略效率,除非您打算每秒运行数千次此代码。 HashSet 是一个非常好的集合,适用于几乎所有实际情况。我建议您避免某些编码人员倾向于以清晰度为代价使他们的代码不必要地高效。
【解决方案2】:

在检查重复项之前,将“排序”向上移动。这样您就可以确保重复项始终彼此相邻,并且您只需要检查邻居。

这里是检测重复的代码:

package luckynumber;

import java.util.Arrays;
import java.util.Random;

public class Main {

    public static void main(String[] args) {

        Random rand = new Random();
        int[] luckyArray = new int[6];

        // build array
        for (int i = 0; i < luckyArray.length; i++) {

            int luckyNumber = rand.nextInt(54) + 1;
            luckyArray[i] = luckyNumber;
        }
        // sort the array before detecting duplicates
        Arrays.sort(luckyArray);
        // detect duplicates in the array
        for (int i = 0; i < luckyArray.length; i++) {
            if (i > 0 && luckyArray[i] == luckyArray[i - 1]) {
                System.out.print("WE HAVE FOUND A DUPLICATE!");
                /* while (luckyArray[i - 1] == luckyArray[i]) { luckyArray[i] =
                 * rand.nextInt(54) + 1; } */
            }
        }
        for (int t = 0; t < luckyArray.length; t++) {

            if (t != 5) {
                System.out.print(luckyArray[t] + "-");
            } else
                System.out.print(luckyArray[t]);
        }
    }
}

当您现在找到重复项并更改数组项时,请确保重新排序并重新检查完整的数组。 剩下的步骤留给读者作为练习。 ;-)

顺便说一句:使用 Set 将使代码更简单。

【讨论】:

  • 我必须排序>检测重复数据>排序>检测重复数据>并再次排序以使其正确显示。但是感谢您的提醒。
【解决方案3】:

这是一个使用 Java 8 流的非常简单的解决方案:

int[] luckyArray = new Random().ints(1, 55).distinct().limit(6).sorted().toArray();

这不会打扰手动检测重复项 - 而是使用 distinct 在选择前 6 个然后对它们进行排序之前删除它们。

【讨论】:

  • 这看起来很棒。问题是当我将它复制到我的 IntelliJ IDEA 时,它不会选择 Java 8 语言,例如“distinct”。有关如何解决该问题的任何链接?为另一种解决方案 +1
  • 您使用的是 Java 8 jdk 吗?如果没有,这将不起作用。
  • 有关如何确保 intellij 指向 Java 8 jdk 的详细信息,请参阅 intellij-support.jetbrains.com/hc/en-us/articles/…
  • 好的,我必须安装那个@sprinter
  • @JonathanScialpi 来吧,它已经发布一年了!接受现在:-)
【解决方案4】:

使用 Java 8:

List<Integer> luckys = 
    IntStream.rangeClosed(1, 54)
             .boxed()
             .collect(collectingAndThen(toList(), l -> {
                 Collections.shuffle(l);
                 return l;
             }))
             .stream()
             .limit(6)
             .collect(toList())

【讨论】:

  • 您可能对我发布的更简单的基于流的解决方案感兴趣。
【解决方案5】:

如果集合不是一个选项,您需要检查每次都遍历您的数组。您当前的检查仅比较序号 1&2、2&3 等。

在插入之前将要检查的幸运数字分配给一个 int,以便与您的数组进行检查。

【讨论】:

    猜你喜欢
    • 2016-10-10
    • 2016-04-13
    • 2012-08-30
    • 2015-08-13
    • 2016-05-05
    • 1970-01-01
    • 2011-12-28
    • 2014-01-11
    相关资源
    最近更新 更多