Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <cmath>
- #include <vector>
- #include <map>
- class ParseExceptions : public std::exception {
- private:
- std::string _error;
- public:
- ParseExceptions() = default;
- explicit ParseExceptions(std::string error) : _error(std::move(error)) {}
- ~ParseExceptions() override = default;
- [[nodiscard]] const char *what() const noexcept override {
- return _error.c_str();
- }
- };
- class BloomFilter {
- public:
- BloomFilter() = default;
- ~BloomFilter() {
- if(_bitset) {
- _bitset->clear();
- delete _bitset;
- }
- }
- std::pair<std::string,std::string> init (uint64_t amount, long double falsePositiveProbability) {
- _probability = falsePositiveProbability;
- _sizeOfBitset = uint64_t(-std::round(amount * std::log2(falsePositiveProbability) / log(2)));
- _amountOfHF = uint64_t(-std::round(std::log2(_probability)));
- if(_sizeOfBitset > 0 && _amountOfHF > 0)
- _bitset = new std::vector<bool>(_sizeOfBitset, false);
- else
- throw ParseExceptions();
- return std::make_pair(std::to_string(_sizeOfBitset),std::to_string(_amountOfHF));
- }
- void addElement(uint64_t key) {
- for (uint64_t indexOfHF = 0; indexOfHF < _amountOfHF; indexOfHF++) {
- uint64_t hash = hashFunc(key, indexOfHF);
- _bitset->at(hash) = true;
- }
- }
- bool searchElement(uint64_t key) {
- for (uint64_t indexOfHF = 0; indexOfHF < _amountOfHF; indexOfHF++) {
- uint64_t hash = hashFunc(key, indexOfHF);
- if (!_bitset->at(hash))
- return false;
- }
- return true;
- }
- std::string printBitset() {
- std::string bitSetStr;
- for (const auto &bit : *_bitset) {
- if (bit)
- bitSetStr += "1";
- else
- bitSetStr += "0";
- }
- return bitSetStr;
- }
- private:
- const uint64_t _mersenne = 2147483647;
- uint64_t hashFunc(uint64_t key, uint64_t index) {
- return (((index + 1) * key + _firstPrimeNumbers.at(index)) % _mersenne) % _sizeOfBitset;
- }
- std::vector<bool> *_bitset = nullptr;
- std::vector<int> _firstPrimeNumbers = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61,
- 67, 71,
- 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149,
- 151, 157, 163, 167, 173,
- 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251,
- 257, 263, 269, 271, 277, 281,
- 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373,
- 379, 383, 389, 397, 401, 409,
- 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491,
- 499, 503, 509, 521, 523, 541,
- 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619,
- 631, 641, 643, 647, 653, 659,
- 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757,
- 761, 769, 773, 787, 797, 809,
- 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887,
- 907, 911, 919, 929, 937, 941,
- 947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013, 1019, 1021, 1031,
- 1033, 1039, 1049, 1051, 1061, 1063, 1069};
- long double _probability = 0.0;
- uint64_t _amountOfHF = 0;
- uint64_t _sizeOfBitset = 0;
- };
- void tokenize(const std::string &str, std::vector<std::string> &tokens, const std::string &delimiters = ".") {
- std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
- std::string::size_type pos = str.find_first_of(delimiters, lastPos);
- while (pos != std::string::npos ||lastPos != std::string::npos ) {
- tokens.push_back(str.substr(lastPos, pos - lastPos));
- lastPos = str.find_first_not_of(delimiters, pos);
- pos = str.find_first_of(delimiters, lastPos);
- }
- }
- void runParse(BloomFilter *filter) {
- bool setConfig = false;
- std::string inputStr;
- // std::chrono::time_point<std::chrono::high_resolution_clock> beg, endd/*, parseBeg, parseEnd*/;
- // beg = std::chrono::system_clock::now();
- while (std::getline(std::cin,inputStr)) {
- try {
- if (inputStr.length() > 0) {
- std::vector<std::string> tokens;
- tokenize(inputStr, tokens, " ");
- auto size = tokens.size();
- if (size <= 3 && size > 0) {
- auto key = tokens.at(0);
- switch (size) {
- case 3:
- if (key == "set" && !setConfig) {
- uint64_t amount = std::stoul(tokens.at(1));
- long double probability = std::stod(tokens.at(2));
- if(probability > 0.0 && probability < 1.0 && amount > 0) {
- auto res = filter->init(amount, probability);
- std::cout << res.first << " " << res.second << std::endl;
- setConfig = true;
- }
- else throw ParseExceptions();
- } else throw ParseExceptions();
- break;
- case 2:
- if (key == "add" && setConfig) {
- uint64_t number;
- number = std::stoull(tokens.at(1));
- filter->addElement(number);
- } else if (key == "search" && setConfig) {
- uint64_t number;
- number = std::stoull(tokens.at(1));
- bool result = filter->searchElement(number);
- std::cout << result << std::endl;
- } else throw ParseExceptions();
- break;
- case 1:
- if (key == "print" && setConfig) {
- std::string output = filter->printBitset();
- std::cout << output << std::endl;
- } else throw ParseExceptions();
- break;
- default:
- throw ParseExceptions();
- }
- }
- }
- }
- catch (ParseExceptions &exc) {
- std::cout << "error\n";
- }
- catch (std::exception &exc) {
- std::cout << "error\n";
- }
- catch (...) {
- std::cout << "ERROR: " << "Unexpected error in search!\n";
- }
- }
- }
- int main() {
- auto *newFilter_p = new BloomFilter();
- runParse(newFilter_p);
- delete newFilter_p;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement