繁体   English   中英

如何生成4个不重复数字的随机数

[英]How can I generate 4 random numbers with unrepeated digits

我想生成4 个随机数,它们不能有重复的数字。

例如4567 ,(它没有像4557这样的重复值)。

我希望它们是随机的

有没有办法实现这一目标?

这将生成没有重复数字的 4 位随机数。

它的工作原理是生成 4 个唯一的数字,就像在电脑游戏中洗一副纸牌一样。 然后它通过乘法和加法简单地建立四位数。

如果数字小于1000 ,则表示使用了0并且在开头。 所以只需选择另一个数字进行调整。

    Random r = new Random();
    for (int k = 0; k < 10; k++) {
        int val = gen(r);
        System.out.println(val);
    }

    static int[] base = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    public static int gen(Random r) {
        int val = 0;
        int s=10;
        for (int i = 0; i < 4; i++) {
            int n = r.nextInt(s);
            val = val * 10 + base[n];
            int save = base[n];
            base[n] = base[--s];
            base[s] = save;
        }
        return val < 1000 ? val * 10 + base[r.nextInt(s)] : val;
    }

这是一个更直接的方法。 哲学与上述相同。 由于所有数字的洗牌,它可能不像以前那样有效。

        // generate four digit numbers that have distinct digits.

        List<Integer> digits = Arrays.asList(0,1,2,3,4,5,6,7,8,9);
        Collections.shuffle(digits);

        // now just use the first four of the shuffled list

        if (digits.get(0) == 0) {
            // for a 4 digit number, first digit can't be zero
            // so choose another.
            digits.set(0, digits.get(4));
        }

        // now use simple arithmetic to create the four digit number.
        int n = 0;
        for (int d : digits.subList(0,4)) {
            n = n * 10 + d;
        }

        System.out.println(n);

我现在沉迷于流。 但是流很慢。 为了显示我写了以下主要方法的缓慢。 “generateWithLoop”方法涵盖了@WJS 的答案。

    public static void main(String[] args) {

        long nanoStart = System.nanoTime();
        generateWithStreams();
        long nanoEnd = System.nanoTime();
        System.out.println("Elapsed time with Streams : " + (nanoEnd - nanoStart) + " nano seconds");

        nanoStart = System.nanoTime();
        generateWithLoop();
        nanoEnd = System.nanoTime();
        System.out.println("Elapsed time with Loop : " + (nanoEnd - nanoStart) + " nano seconds");
    }

控制台输出:

Streams 已用时间:81367089 纳秒

循环运行时间:75093 纳秒

随着流:

    public static void generateWithStreams() {

        List<Integer> orderedList = getOrderedList();

        for (int i = 0; i < 4; i++) {
            List<Integer> shuffledList = getShuffledList(orderedList);
            System.out.println(get4DigitNumber(shuffledList));
        }

    }

    public static List<Integer> getOrderedList() {
        return IntStream.range(0, 10).boxed().collect(Collectors.toList());
    }

    public static List<Integer> getShuffledList(List<Integer> list) {
        return list.stream().sorted((o1, o2) -> ThreadLocalRandom.current().nextInt(-1, 2)).collect(Collectors.toList());
    }

    public static Integer get4DigitNumber(List<Integer> shuffledList) {
        final Integer LIMIT = shuffledList.get(0).equals(0) ? 5 : 4;
        return shuffledList.stream().limit(LIMIT).reduce(0, (sum, current) -> sum * 10 + current);
    }

带循环:

    public static void generateWithLoop() {
        Random r = new Random();
        for (int k = 0; k < 4; k++) {
            int val = gen(r);
            System.out.println(val);
        }

    }

    static int[] base = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

    public static int gen(Random r) {
        int val = 0;
        int s = 10;
        for (int i = 0; i < 4; i++) {
            int n = r.nextInt(s);
            val = val * 10 + base[n];
            int save = base[n];
            base[n] = base[--s];
            base[s] = save;
        }
        return val < 1000 ? val * 10 + base[r.nextInt(s)] : val;
    }
public static void main(String[] args) {
    List<Integer> list= new ArrayList<>();
    for(int j = 0; j < 10; j++){
        list.add(j);
    }
    Collections.shuffle(list);
    String randomDigit= "";
    for(int j = 0; j < 4; j++){
        randomDigit+= list.get(j).toString();
    }
    System.out.println(randomDigit);
}

这是将字符串转换为 int。 但这会起作用,您可以使用它。

脚步:

  1. 创建一个List ,将保存生成的 4 位数字的每个单独的数字
  2. 为1到9之间的单位生成一个随机数,并将其放入列表中
  3. 创建一个循环,为十位到最后一位生成一个0到9之间的随机数; 并且每次都将随机数放入您的列表中。 检查列表中未包含的每次迭代的数量

最终列表的大小现在是 4; 将这 4 个个体组合成一个String ,并转换为Integer

List<Integer> myNumber = new ArrayList<Integer>();
Random r = new Random();

// Generate a random number between 1 and 9 for units place
myNumber.add(r.nextInt(9) + 1);// adding 1 to avoid 0 in the units place

// Generate a random number between 0 and 9 for 10's and upcoming places
do {
    Integer num = r.nextInt(10);
    // Check the list doesn't contain that number
    if (!myNumber.contains(num)) {
        myNumber.add(num);
    }
}while (myNumber.size() < 4);

StringBuilder numStr = new StringBuilder();
for (int i = 0; i < myNumber.size(); i++)
    numStr.append(myNumber.get(i));

System.out.println(Integer.parseInt(numStr.toString()));

Java-8开始使用streamLambda 的解决方案:

  public static void main(String[] args) {
        Map<String, String> collect = IntStream.rangeClosed(1, 9).boxed()
                .flatMap(x -> IntStream.rangeClosed(0, 9).boxed()
                        .flatMap(y -> IntStream.rangeClosed(0, 9).boxed()
                                .flatMap(z -> IntStream.rangeClosed(0, 9).boxed()
                                        .flatMap(w -> IntStream.rangeClosed(1, 9).boxed().map(s -> s.toString()).filter(e -> noneRepete(x, y, z, w))
                                                .map(k -> x.toString() + y.toString() + z.toString() + w.toString())))))
                .collect(Collectors.toMap(Function.identity(), s -> s, (a, b) -> a));
        collect.keySet().forEach(System.out::println);
    }

    public static boolean noneRepete(Integer a, Integer b, Integer c, Integer d) {
        if (! a.equals(b) && ! a.equals(c) && ! a.equals(d) && a !=0) {
            if (! b.equals(c) && ! b.equals(d)) {
                return ! c.equals(d);
            }
        }
        return false;
    }

解释:

在这里,我们将整数流从 1 展平到 9(第一个数字不能为 0)。 同时,我们进一步将整数流从 0 展平到 9。上述过程又进行了 2 次,从而使其成为四位数字,我们有一个自定义过滤器,可确保所有四位数字都是唯一的。

最后,我们将它们收集为键和值,以确保数字是唯一的,并且映射中的键本身也是唯一的。

暂无
暂无

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

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