隨機數擴充

zxc123e發表於2015-08-20

1)題目
給定一個等概率隨機產生1~5的隨機函式rand1To5如下:
public int rand1To5() {
return (int) (Math.random() * 5) + 1;
}
除此之外不能使用任何額外的隨機機制,請用rand1To5實現等概率隨機產生1~7的隨機函式rand1To7。

 Random random = new Random();
            int y = random.nextInt(5)*5+random.nextInt(5);
            if(y >= 0 && y<= 20)
            {
                System.out.println(y%7+1);
            }

(2)補充題目
給定一個以p概率產生0,以1-p概率產生1的隨機函式rand01p如下:
public int rand01p() {
// you can change p as you like
double p = 0.83;
return Math.random() < p ? 0 : 1;
}
除此之外不能使用任何額外的隨機機制,請用rand01p實現等概率隨機產生1~3的隨機函式rand1To3。

    public int rand01p() {
        // you can change p as you like
        double p = 0.83;
        return Math.random() < p ? 0 : 1;
    }
    public int rand01Or10() {
        int num;
        do {
            num = rand01p();
        } while (num == rand01p());
        return num == 1 ? 1 : 0;
    }

    public void rand1to3()
    {
        int x = rand01Or10()*2 + rand01Or10();
        System.out.println(x);
    }

(3)進階題目
給定一個等概率隨機產生1~M的隨機函式rand1ToM如下:
public int rand1ToM(int m) {
return (int) (Math.random() * m) + 1;
}
除此之外不能使用任何額外的隨機機制。有兩個輸入引數分別為m和n,請用rand1ToM(m)實現等概率隨機產生1~n的隨機函式rand1ToN。

    public int rand1ToM(int m) {
        return (int) (Math.random() * m) + 1;
    }
    public int rand1ToN(int n, int m) {
        int[] nMSys = getMSysNum(n - 1, m);
        int[] randNum = getRanMSysNumLessN(nMSys, m);
        return getNumFromMSysNum(randNum, m) + 1;
    }

    // 把value轉成m進位制的數
    public int[] getMSysNum(int value, int m) {
        int[] res = new int[32];
        int index = res.length - 1;
        while (value != 0) {
            res[index--] = value % m;
            value = value / m;
        }
        return res;
    }
    // 等概率隨機產生一個0~nMsys範圍上的數,只不過是m進製表達的。
    public int[] getRanMSysNumLessN(int[] nMSys, int m) {
        int[] res = new int[nMSys.length];
        int start = 0;
        while (nMSys[start] == 0) {
            start++;
        }
        int index = start;
        boolean lastEqual = true;
        //精粹,控制隨機數的範圍在0~n-1(m進製表示)之間
        while (index != nMSys.length) {
            res[index] = rand1ToM(m) - 1;
            if (lastEqual) {
                if (res[index] > nMSys[index]) {
                    index = start;
                    lastEqual = true;
                    continue;
                } else {
                    lastEqual = res[index] == nMSys[index];
                }
            }
            index++;
        }
        return res;
    }
    // 把m進位制的數轉成10進位制
    public int getNumFromMSysNum(int[] mSysNum, int m) {
        int res = 0;
        for (int i = 0; i != mSysNum.length; i++) {
            res = res * m + mSysNum[i];
        }
        return res;
    }

相關文章