刚看到一个blooming filter 的hash函数的实现,里面用到了随机函数。
protected int[] getHashIndexes(E obj) {
int[] indexes = new int[numHashFunc];
long seed = 0;
byte[] digest;
try {
MessageDigest md = MessageDigest.getInstance(“MD5”);
md.update(obj.toString().getBytes());
digest = md.digest();
for (int i = 0; i < 6; i++) {
seed = seed | (((long)digest[i] & 0xFF))<<(8*i);
}
} catch (NoSuchAlgorithmException e) {}
Random gen = new Random(seed);
for (int i = 0; i < numHashFunc; i++) {
indexes[i] = gen.nextInt(bitArraySize);
}
return indexes;
}
刚开始还比较疑问,在hash函数中用随机函数来生成hash值,既然是随机的,那么在add(A), 和find(A) 的时候都需要调用这个hash函数来生成key, 由于随机函数的存在,那么相同的value生成的Key那应该是不一样的,那这个hash还有什么用呢?
后来想到了随机函数的伪随机的问题,也就是当一个随机函数给定一个相同的seed(种子)的时候,其后续相同次数生成的随机数是相同的, 因为随机函数的实现都是以seed为起点,做一些运算生成其他的随机数。
下面对C中的rand()函数和Java中Random类做了实验。
srand(0);
vector<int> lvFirstArray;
for(int i = 0; i < 100; i ++)
lvFirstArray.push_back(rand()); //以0为seed生成100个随机数
srand(0);
for(int i = 0; i < 100; i ++)
assert(rand() == lvFirstArray[i]);//重新以0为seed生成100个随机数和前面生成100个随机数相同
这也就为什么教课书里面要以clock()为seed来生成随机数的原因吧。
import java.util.Random;
public class RandomDemo {
public static void main(String[] args) {
Random r1 = new Random(10);
Random r2 = new Random(10);
//循环打印两次
for (int i = 0; i < 2; i++) {
System.out.println(r1.nextInt());
System.out.println(r2.nextInt());
}
}
}