@
dazhangpan 可以换一个思路,我认为这个题目,考察的内容,非常接近 RC4 的流式加密算法,有个文章链接:
https://www.cnblogs.com/gambler/p/9075415.html题目中给出的 foo()函数 [产生 0-1 随机数] ,我们可以用来初始化 流式加密的 init 映射状态。随后的 随机数产生,可以完全不依赖 foo()函数,完全依靠流式加密的方式,产生概率 10%的 [0-9]
==============Java 代码如下==================
package com.ic2y;
public class RandomNumber {
private static int MAPPING_LEN = 10;
//映射 0-9 的 关系
private int[] mapping = new int[MAPPING_LEN];
private int i = 0;
private int j = 0;
public RandomNumber(){
//初始化 mapping,再进行打乱
for(int i = 0;i < 10;++i){
mapping[i] = i;
}
//shuffle 算法,
for ( int i = MAPPING_LEN; i > 0; i-- ){
swap(getRandomLessTen(), i - 1);
}
}
private int getRandomLessTen(){
int val;
do {
val = doGetRandomLessTen();
if(val < 10){
return val;
}
}while (true);
}
private int doGetRandomLessTen(){
int val = 0;
for(int i = 0;i <4;++i){
val = val * 2 + foo();
}
return val;
}
//已知的产生 0 1 随机数的 函数
private int foo(){
return (int)System.currentTimeMillis() % 2;
}
//外界调用 boo 产生 0-9 随机数
public int boo(){
i = (i + 1) % MAPPING_LEN;
j = (j + mapping[i]) % MAPPING_LEN;
swap(i,j);
return mapping[(mapping[i] + mapping[j]) % MAPPING_LEN];
}
private void swap(int l,int r){
int tmp = mapping[l];
mapping[l] = mapping[r];
mapping[r] = tmp;
}
public static void main(String[] args){
RandomNumber r = new RandomNumber();
int testNumber = 100000;
int[] f = new int[10];
for(int i = 0;i < testNumber;++i){
++f[r.boo()];
}
float fTestNumber = (float)testNumber;
for(int i = 0; i < 10;++i){
System.out.println(String.format("Num:%d Probability:%.2f count:%d",i,f[i] / fTestNumber,f[i]));
}
}
}
=======结果=======
Num:0 Probability:0.10 count:9863
Num:1 Probability:0.10 count:10051
Num:2 Probability:0.10 count:10054
Num:3 Probability:0.10 count:10024
Num:4 Probability:0.10 count:10031
Num:5 Probability:0.10 count:9942
Num:6 Probability:0.10 count:10007
Num:7 Probability:0.10 count:9877
Num:8 Probability:0.10 count:10083
Num:9 Probability:0.10 count:10068