从5随机到7随机及其扩展 【题目】 给定一个等概率随机产生1~5的随机函数rand1To5如下: public int rand1To5() { return (int) (Math.random() * 5) + 1; } 除此之外不能使用任何额外的随机机制,请用rand1To5实现等概率随机产生1~7的随机函数rand1To7。 【补充题目】 给定一个以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~6的随机函数rand1To6。 【进阶题目】 给定一个等概率随机产生1~M的随机函数rand1ToM如下: public int rand1ToM(int m) { return (int) (Math.random() * m) + 1; } 除此之外不能使用任何额外的随机机制。有两个输入参数分别为m和n,请用rand1ToM(m)实现等概率随机产生1~n的随机函数rand1ToN。 public int rand1To5() { return (int) (Math.random() * 5) + 1; } public int rand1To7() { int num = 0; do { num = (rand1To5() - 1) * 5 + rand1To5() - 1; } while (num > 20); return num % 7 + 1; } public int rand01p() { // you can change p as you like double p = 0.83; return Math.random() < p ? 0 : 1; } public int rand01() { int num; do { num = rand01p(); } while (num == rand01p()); return num == 1 ? 1 : 0; } public int rand0To3() { return rand01() * 2 + rand01(); } public int rand1To6() { int num = 0; do { num = rand0To3() * 4 + rand0To3(); } while (num > 11); return num % 6 + 1; } 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; 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; }
点赞 9
牛客网
牛客企业服务