Lintcode 555. Counting Bloom Filter
Description
Implement a counting bloom filter. Support the following method:
add(string). Add a string into bloom filter.
contains(string). Check a string whether exists in bloom filter.
remove(string). Remove a string from bloom filter.
Have you met this question in a real interview?
Example
Example1
Input:
CountingBloomFilter(3)
add(“lint”)
add(“code”)
contains(“lint”)
remove(“lint”)
contains(“lint”)
Output:
[true,false]
Example2
Input:
CountingBloomFilter(3)
add(“lint”)
add(“lint”)
contains(“lint”)
remove(“lint”)
contains(“lint”)
Output:
[true,true]
这题跟Standard Bloom Filter很像,只是不能用bitset了,因为每个pos都要记counting:add()对各个pos的counting加1, remove()对各个pos的 counting–。contain()检查每个pos的counting是不是>0。
class HashClass{
public:
HashClass(int c, int s) : cap(c), seed(s) {}
int hashFunc(string &value) {
int ret = 0;
for (int i = 0; i < value.size(); ++i) {
ret += seed * ret + value[i];
ret %= cap;
}
return ret;
}
private:
int cap, seed;
};
class CountingBloomFilter {
public:
/*
* @param k: An integer
*/
CountingBloomFilter(int k) {
this->k = k;
for (int i = 0; i < k; ++i) {
hashVec.push_back(new HashClass(100000 + i, 2 *i + 3));
}
bitSets.resize(100000 + k, 0);
}
/*
* @param word: A string
* @return: nothing
*/
void add(string &word) {
for (int i = 0; i < k; ++i) {
bitSets[hashVec[i]->hashFunc(word)]++;
}
}
/*
* @param word: A string
* @return: nothing
*/
void remove(string &word) {
for (int i = 0; i < k; ++i) {
int pos = hashVec[i]->hashFunc(word);
if (bitSets[pos] > 0)
bitSets[pos]--;
}
}
/*
* @param word: A string
* @return: True if contains word
*/
bool contains(string &word) {
for (int i = 0; i < k; ++i) {
if (!bitSets[hashVec[i]->hashFunc(word)])
return false;
}
return true;
}
private:
int k;
vector<HashClass *> hashVec;
vector<int> bitSets;
};