Java用n種方法編寫實現雙色球隨機搖號案例



之前我用JavaScript編寫過一個實現雙色球隨機搖號的案例, 點擊此處查看,今天我再用Java語言來實現這一效果。

規則

那么首先我們要搞清楚規則是什么:

雙色球投注區分為紅球號碼區和藍球號碼區
紅球號碼范圍為01~33,藍球號碼范圍為01~16
雙色球每期從33個紅球中開出6個號碼,從16個藍球中開出1個號碼作為中獎號碼
雙色球玩法即是競猜開獎號碼的6個紅球號碼和1個藍球號碼,順序不限

簡單來說,就是通過隨機,紅球就是在1~33中隨機出來6個互不相同的數字,藍球則是產生一個1 ~16之間的數字。那么難點當然在於紅球,如何確保不重復呢?

實現方式一

當然是用集合了,因為集合的性質就在於,里面的元素互不重復。接下來我們就用集合來實現:

package day_11_25;

import java.util.HashSet;
import java.util.Random;
import java.util.Set;

/** * 雙色球 * 紅球1~33 籃球1~16 * * @author soberw */
public class DoubleBall2 {
    public static void main(String[] args) {
        Random random = new Random();
        Set<Integer> red = new HashSet<Integer>();
        do {
            red.add(random.nextInt(33) + 1);
        } while (red.size() != 6);
        System.out.print("{ ");
        red.forEach((value) -> {
            System.out.printf("[%02d] ", value);
        });
        System.out.print("}");
        System.out.printf("{ [%02d] }", random.nextInt(16) + 1);
    }
}

運行結果:
在這里插入圖片描述

實現方式二

那么如果不用集合而用數組呢?我們都知道Java的數組比較死板,就是一旦定義,就不能再更改長度,而且在聲明的時候一定要指定長度或者初始化值。那么如果想用數組實現呢,代碼如下:

package day_11_25;

import java.util.Random;

/** * 雙色球 * 紅球1~33 籃球1~16 * * @author soberw */
public class DoubleBall3 {
    public static void main(String[] args) {
        Random random = new Random();
        //放紅球
        int[] red = new int[6];
        for (int i = 0; i < red.length; i++) {
            boolean flag = true;
            int redRAn = random.nextInt(33) + 1;
            while (flag) {
                for (int j = 0; j < red.length; j++) {
                    if (red[j] == redRAn) {
                        flag = false;
                        break;
                    }
                }
                if (flag) {
                    red[i] = redRAn;
                    break;
                }
            }
        }
        System.out.print("{ ");
        for (int i : red) {
            System.out.printf("[%02d] ", i);
        }
        System.out.print("}");
        System.out.printf("{ [%02d] }", random.nextInt(16) + 1);
    }
}

運行結果:
在這里插入圖片描述

實現方式三

其實用數組的實現方式有很多,上面這種采用了三重循環嵌套,如果邏輯性不強,很難理解為什么這樣子寫,下面分享另一種寫法,相比於上一種寫法,這種的思路是創建一個基數數組base存放1~33所有的號碼球,每次隨機抽取出一個,然后將base 中對應號碼球的賦值為0,每次抽取的時候都會先判斷是不是為0,如果是0就說明已經被抽走了,那么就繼續隨機,直到不再重復為止。確保不會重復:

package day_11_25;

import java.util.Random;

/** * 雙色球 * 紅球1~33 籃球1~16 * * @author soberw */
public class DoubleBall {
    public static void main(String[] args) {
        Random ran = new Random();
        //基數組,從這里抽數放入red
        int[] base = new int[33];
        //存放紅球
        int[] red = new int[6];
        int ranIndex;
        //給base元素依次賦值1~33
        for (int i = 1; i <= base.length; i++) {
            base[i - 1] = i;
        }

        for (int i = 0; i < red.length; i++) {
            while (true) {
                //隨機base的下標
                ranIndex = ran.nextInt(33);
                //判斷是不是被抽走了,被抽走了就繼續隨機,沒有的話就放入red,並將base中對應的賦值為0
                if (0 != base[ranIndex]) {
                    red[i] = base[ranIndex];
                    base[ranIndex] = 0;
                    break;
                }
            }
        },
        System.out.print("{ ");
        for (int i : red) {
            System.out.printf("[%02d] ", i);
        }
        System.out.print("}");
        System.out.printf("{ [%02d] }", ran.nextInt(16) + 1);

    }
}

運行結果:
在這里插入圖片描述

實現方式四

當然我們也可以借助數組工具類Arrays中的二分查找方法 binarySearch()來判斷是否已經存在,但是前提是必須在查找前先排序,因為二分查找的前提就是要確保數組是有序的:

package day_11_25;

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

/** * 雙色球 * 紅球1~33 籃球1~16 * * @author soberw */
public class DoubleBall4 {
    public static void main(String[] args) {
        Random random = new Random();
        //放紅球
        int[] red = new int[6];
        Arrays.fill(red,33);
        //存放號碼球
        int ranRed;
        for (int i = 0; i < red.length; i++) {
            boolean flag = true;
            //確保數組有序
            Arrays.sort(red);
            while (flag) {
                ranRed = random.nextInt(33) + 1;
                //判斷數組中是否存在此元素
                if (Arrays.binarySearch(red, ranRed) < 0) {
                    flag = false;
                    red[i] = ranRed;
                }
            }
        }
        System.out.print("{ ");
        for (int i : red) {
            System.out.printf("[%02d] ", i);
        }
        System.out.print("}");
        System.out.printf("{ [%02d] }", random.nextInt(16) + 1);
    }
}

運行結果:
在這里插入圖片描述

這里需要注意一點,Arrays.binarySearch()方法如果找不到元素,返回的不是-1,而是一個小於0的數,這個數是多少呢,查看API手冊得知:
在這里插入圖片描述
我在使用的時候就栽過坑,讓其等-1,結果陷入死循環。。。

實現方法五

那么上一個方法存在的問題就是,每次判斷之前我還要對數組進行排序,雖然這是內置的算法不用我們自己在寫了,但是總感覺還是有待優化一下。於是,就有了第五種方法:)
使用Vector類完成,它的優勢在於,它是動態的,可以動態添加數據,最主要的是,它內置了超級多的方法,相比於原始數組的死板,實在是強大許多:

package day_11_25;

import java.util.Random;
import java.util.Vector;

/** * 雙色球 * 紅球1~33 籃球1~16 * * @author soberw */
public class DoubleBall5 {
    public static void main(String[] args) {
        Random random = new Random();
        //聲明一個空數組用於存放紅球
        Vector<Integer> red = new Vector<Integer>();
        //超出六個退出
        while (red.size() < 6) {
            int ranRed = random.nextInt(33) + 1;
            //如果不存在則添加
            if (!red.contains(ranRed)) {
                red.add(ranRed);
            }
        }
        System.out.print("{ ");
        for (int i : red) {
            System.out.printf("[%02d] ", i);
        }
        System.out.print("}");
        System.out.printf("{ [%02d] }", random.nextInt(16) + 1);
    }
}

運行結果:
在這里插入圖片描述
這是我目前想到的五種方式,那么你覺得那種好用呢?
或者你有更好的方法,歡迎評論區補充,大家一起探討一起學習!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM