簡體   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