现在检测某一元素是否在该集合中。标明某个元素是否在集合中所需的 k 个位置都按照如上的方法设置为 “1”,但是该方法可能会使算法错误的认为某一原本不在集合中的元素却被检测为在该集合中(False Positives),该概率由以下公式确定:
1 - (1 - 1 / m) ^ k*n ≈ (1 - e ^ (-k * n / m)) ^ k
其实上述结果是在假定由每个 Hash 计算出需要设置的位(bit) 的位置是相互独立为前提计算出来的,不难看出,随着 m (位数组大小)的增加,假正例(False Positives)的概率会下降,同时随着插入元素个数 n 的增加,False Positives的概率又会上升,对于给定的m,n,如何选择Hash函数个数 k 由以下公式确定:
m / n * ln2 ≈ 0.7 * m / n
此时False Positives的概率为:2 ^ -k ≈ 0.6185 ^ (m / n)
而对于给定的False Positives概率 p,如何选择最优的位数组大小 m 呢,
m = -n * lnp / (ln2) ^ 2
上式表明,位数组的大小最好与插入元素的个数成线性关系,对于给定的 m,n,k,假正例概率最大为:(1 - e ^ (-k * (n + 0.5)/(m - 1))) ^ k
值得注意的是,k值并非越大越好。可以证明,当 k = ln(2) * m/n 时出错的概率是最小的。
/*set flag on a certain index bit*/ intbitmap_set(unsignedchar * bitmap, int index, int flag){ //index range should have been checked outside! int seg = index / 8; int off = index % 8; unsignedchar p = 0x1<< off; if(flag == 1) bitmap[seg] |= p; elseif(flag == 0) bitmap[seg] &= ~p; else return0; return1; }
/*get flag on a certain index bit*/ intbitmap_get(unsignedchar * bitmap, int index){ ///check index range outside first! int seg = index / 8; int off = index % 8; unsignedchar p = 0x1 << off; int tmp = bitmap[seg] & p; return tmp > 0 ? 1 :0; } /*free bitmap*/ voidbitmap_free(unsignedchar * bitmap){ free(bitmap); *bitmap = NULL; }
/*Hash string with 11 different hash function(flag = 0) Or Search string in a maked bloom filter(flag = 1) */ intbloomfilter_insert(unsignedchar * bitmap, char* emailstring, int flag){ unsignedint index;