70 lines
1.6 KiB
C++
70 lines
1.6 KiB
C++
#include <cstdio>
|
|
#include <string>
|
|
#include <set>
|
|
|
|
/*
|
|
* Bloom filters
|
|
* - n bit array
|
|
* - k hash functions
|
|
* - add_elem:
|
|
* - get the set of {h_i(elem) mod n} and mark them 1
|
|
* - check elem:
|
|
* - x is elem
|
|
* - generate same positions set, if any are false this does not belong
|
|
* for sure
|
|
* - no guarantees on presence
|
|
*/
|
|
|
|
const int N = 1024;
|
|
const int K = 5;
|
|
std::vector<bool> bf(N);
|
|
|
|
int hash_i(int i, int x) {
|
|
switch (i) {
|
|
case 1:
|
|
return x; // h1(i) = i is perfectly ok, std::hash will do the same
|
|
case 2:
|
|
// here we need something better
|
|
// the | 1 makes it co-rime to N always
|
|
return std::hash<std::string>{}(std::to_string(x)) | 1;
|
|
default:
|
|
return hash_i(1, x) + i * hash_i(2, x);
|
|
}
|
|
}
|
|
|
|
void add(int elem){
|
|
for(int i = 1;i<=K;i++){
|
|
int hash = hash_i(i, elem) % N;
|
|
bf[hash] = 1;
|
|
}
|
|
}
|
|
|
|
bool missing(int elem){
|
|
for(int i = 1;i<=K;i++){
|
|
int hash = hash_i(i, elem) % N;
|
|
if(!bf[hash]) return true; // actually missing
|
|
}
|
|
return false; // may be present
|
|
}
|
|
|
|
int main() {
|
|
srand(time(nullptr));
|
|
std::set<int> actually_present{};
|
|
const int LIM = 500;
|
|
for(int i = 1; i< LIM;i++){
|
|
if(rand()&1){
|
|
actually_present.insert(i);
|
|
add(i);
|
|
}
|
|
}
|
|
|
|
int wrong = 0;
|
|
for(int i=1;i<LIM;i++){
|
|
bool true_missing = !actually_present.count(i);
|
|
bool bloom_missing = missing(i);
|
|
if( true_missing != bloom_missing ) wrong++;
|
|
}
|
|
|
|
std::printf("%d/%d incorrect\n", wrong, actually_present.size());
|
|
}
|