C++|哈希應用->布隆過濾器

目錄

一、概念

二、模擬實現

三、布隆過濾器擴展應用


?

上一篇章學習了位圖的使用,但它只適用于整數,對于要查詢字符串是否在不在,位圖并不能解決。所以針對這一問題,布隆過濾器可以派上用場,至于布隆過濾器是什么,其實并沒有什么神奇的,就是在位圖上套了哈希函數罷了,這兩者組合起來就是布隆過濾器,而字符串就可以通過哈希函數轉換成整數映射到位圖當中去。?

一、概念

布隆過濾器是由布隆(Burton Howard Bloom)在1970年提出的一種緊湊型的、比較巧妙的概念性數據結構,特點是高效地插入和查詢,可以用來告訴你“某樣東西一定不存在或者可能存在”,他是用多個哈希函數,將一個數據映射到位圖結構中。此種方式不僅可以提升查詢效率,也可以節省大量的內存空間。

原理分析:?

我們來進行分析,為什么不存在是一定的,而存在是可能的,以及為什么要這樣做。

首先來解釋為什么要用多個哈希函數。

我們知道,字符串可以通過哈希函數轉換成整數,但是哈希沖突是避免不了的,可能存在多個字符串通過哈希函數都得到了一樣的整數,所以,為了盡量的減少哈希沖突,可以使用多個哈希函數,讓字符串通過多個哈希函數得到多個映射位置,只要不是多個映射位置都相同,就不會沖突,這樣大大提高了效率。至于要用幾個哈希函數是適合的。

這里有一份研究:(轉載詳解布隆過濾器的原理,使用場景和注意事項 - 知乎 (zhihu.com))

其中誤報率就是哈希沖突率?

其中k、m、n滿足:

?其中k、m、p滿足:

我們可以發現,哈希函數用的越多,哈希沖突率就越低,但是哈希函數到3之后,誤報率已經很低了,其次,當哈希函數、插入元素固定,所開空間越大,誤報率也越低。

用一張圖來表示通過哈希函數映射到位圖中:

那么綜上,即使采用了多個哈希函數,也依然可能會存在哈希沖突,所以在判斷東西在不在時,若返回的是存在,這有可能是誤判,說明映射的位置依然可能完全相同,而不存在時,說明映射的位置不完全相同,這是正確的結果,為了確保沖突率,我們在模擬實現的時候就采用3個哈希函數。

二、模擬實現

#include "MyBitSet.h"//在上一篇章已實現
struct BKDRHash
{size_t operator()(const string& key){size_t hash = 0;for (auto e : key){//BKDRhash *= 31;hash += e;}return hash;}
};struct APHash
{size_t operator()(const string& key){size_t hash = 0;for (size_t i = 0; i < key.size(); i++){if ((i & 1) == 0){hash ^= ((hash << 7) ^ key[i] ^ (hash >> 3));}else{hash ^= (~((hash << 11) ^ key[i] ^ (hash >> 5)));}}return hash;}
};
struct DJHash
{size_t operator()(const string& key){register size_t hash = 5381;for(auto e : key){hash += (hash << 5) + e;}return hash;}
};
namespace bit
{template<size_t N, class K = string, //默認輸入的是字符串class HashFunc1 = BKDRHash,class HashFunc2 = APHash,class HashFunc3 = DJHash>class BloomFilter{public:void set(const K& key){//獲取三個映射位置int hash1 = HashFunc1()(key) % N;int hash2 = HashFunc2()(key) % N;int hash3 = HashFunc3()(key) % N;_blf.set(hash1);_blf.set(hash2);_blf.set(hash3);}bool test(const K& key){//key不存在是準確的。int hash1 = HashFunc1()(key) % N;if (_blf.test(hash1) == false)return false;int hash2 = HashFunc2()(key) % N;if (_blf.test(hash2) == false)return false;int hash3 = HashFunc3()(key) % N;if (_blf.test(hash3) == false)return false;//key存在可能有誤判return true;}private:bitset<N> _blf;};
}void TestBF1()
{bit::BloomFilter<100> bf;bf.set("豬八戒");bf.set("沙悟凈");bf.set("孫悟空");bf.set("二郎神");cout << bf.test("豬八戒") << endl;cout << bf.test("沙悟凈") << endl;cout << bf.test("孫悟空") << endl;cout << bf.test("二郎神") << endl;cout << bf.test("二郎神1") << endl;cout << bf.test("二郎神2") << endl;cout << bf.test("二郎神 ") << endl;cout << bf.test("太白晶星") << endl;
}void TestBF2()
{srand(time(0));const size_t N = 100000;bit::BloomFilter<N * 10> bf;std::vector<std::string> v1;//std::string url = "https://www.cnblogs.com/-clq/archive/2012/05/31/2528153.html";std::string url = "豬八戒";for (size_t i = 0; i < N; ++i){v1.push_back(url + std::to_string(i));}for (auto& str : v1){bf.set(str);}// v2跟v1是相似字符串集(前綴一樣),但是不一樣std::vector<std::string> v2;for (size_t i = 0; i < N; ++i){std::string urlstr = url;urlstr += std::to_string(9999999 + i);v2.push_back(urlstr);}size_t n2 = 0;for (auto& str : v2){if (bf.test(str)) // 誤判{++n2;}}cout << "相似字符串誤判率:" << (double)n2 / (double)N << endl;// 不相似字符串集std::vector<std::string> v3;for (size_t i = 0; i < N; ++i){//string url = "zhihu.com";string url = "孫悟空";url += std::to_string(i + rand());v3.push_back(url);}size_t n3 = 0;for (auto& str : v3){if (bf.test(str)){++n3;}}cout << "不相似字符串誤判率:" << (double)n3 / (double)N << endl;
}

測試:

#include <string>
#include "MyBloomFilter.h"int main()
{TestBF2();return 0;
}

?輸出結果:

三、布隆過濾器擴展應用

1.給兩個文件,分別由100億個字符串,只有1G內存,如何找到兩個文件交集?

假設每個字符串占50個字節,那么100億就是5000字節,約等于500G,內存肯定存不下,此時可以采用哈希切分。如圖:

?

2.給一個超過100G大小的log file,log中存著IP地址,設計算法找到出現次數最多的IP地址?

與第一題類似,先進行哈希切分,然后通過map統計每個小文件中IP地址出現的次數進行比較即可。?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/42134.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/42134.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/42134.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

全球首款商用,AI為視頻自動配音配樂產品上線

近日&#xff0c;海外推出了一款名為Resona V2A的產品&#xff0c;這是全球首款商用視頻轉音頻 (V2A) 技術產品。這項突破性技術利用AI&#xff0c;僅憑視頻數據即可自動生成高質量、與上下文相關的音頻&#xff0c;包括聲音設計、音效、擬音和環境音&#xff0c;為電影制作人、…

linux內核開發之tftp服務搭建

TFTP (Trivial File Transfer Protocol) 是一個簡單的文件傳輸協議&#xff0c;通常用于在計算機網絡中進行文件傳輸。它是FTP的一個簡化版本&#xff0c;主要用于在局域網內部傳輸文件。 主要特點和用途&#xff1a; 簡單性&#xff1a; TFTP設計簡單&#xff0c;功能有限&am…

Hi3861 OpenHarmony嵌入式應用入門--TCP Server

本篇使用的是lwip編寫tcp服務端。需要提前準備好一個PARAM_HOTSPOT_SSID宏定義的熱點&#xff0c;并且密碼為PARAM_HOTSPOT_PSK LwIP簡介 LwIP是什么&#xff1f; A Lightweight TCP/IP stack 一個輕量級的TCP/IP協議棧 詳細介紹請參考LwIP項目官網&#xff1a;lwIP - A Li…

主流I/O模型總結

異步通知I/O模型(Windows) #include<string.h> #include<stdio.h> #include<WinSock2.h> #define BUF_SIZE 100 void CompressSockets(SOCKET hSockArr[], int idx, int total); void CompressEvent(WSAEVENT hEventArr[], int idx, int total); char msg[B…

奇景光電戰略投資Obsidian,共筑熱成像技術新未來

5月29日,業界領先的IC設計公司奇景光電宣布,將對熱成像傳感器解決方案制造商Obsidian進行戰略性投資,并以主要投資者的身份,參與到Obsidian的可轉換票據融資活動中。雖然奇景光電并未公開具體的投資金額,但這一舉動無疑向市場傳遞了一個明確的信號:奇景光電對Obsidian的技…

【INTEL(ALTERA)】為什么我會看到包含管道橋的Nios II設計出現 Flash Programmer 問題?

目錄 說明 解決方法 說明 簡化地址解碼的常見解決方案是將連接到Avalon管道橋后Nios II處理器的數據主的外設放置&#xff0c;有時可能包括一些內存 IP&#xff0c;如片上 RAM。 但是&#xff0c;如果預期內存包含Nios II程序代碼&#xff0c;則應該以與Nios II指令主連接到…

10、matlab中字符、數字、矩陣、字符串和元胞合并為字符串并將字符串以不同格式寫入讀出excel

1、前言 在 MATLAB 中&#xff0c;可以使用不同的數據類型&#xff08;字符、數字、矩陣、字符串和元胞&#xff09;合并為字符串&#xff0c;然后將字符串以不同格式寫入 Excel 文件。 以下是一個示例代碼&#xff0c;展示如何將不同數據類型合并為字符串&#xff0c;并以不…

【Mindspore進階】-03.ShuffleNet實戰

ShuffleNet圖像分類 當前案例不支持在GPU設備上靜態圖模式運行&#xff0c;其他模式運行皆支持。 ShuffleNet網絡介紹 ShuffleNetV1是曠視科技提出的一種計算高效的CNN模型&#xff0c;和MobileNet, SqueezeNet等一樣主要應用在移動端&#xff0c;所以模型的設計目標就是利用有…

如何在Java中實現自動化測試和集成測試

如何在Java中實現自動化測試和集成測試 大家好&#xff0c;我是免費搭建查券返利機器人省錢賺傭金就用微賺淘客系統3.0的小編&#xff0c;也是冬天不穿秋褲&#xff0c;天冷也要風度的程序猿&#xff01; 自動化測試和集成測試是現代軟件開發過程中至關重要的環節。Java作為一…

分享實現地鐵車輛側面圖

簡介 通過偽類和關鍵幀動畫實現地鐵車輛側面圖 在線演示 偽元素和關鍵幀動畫 實現代碼 <!DOCTYPE html><html><head> <meta http-equiv"Content-Type" content"text/html; charsetutf-8" /> <meta http-equiv"X-UA-Co…

設計模式之單例模式(Java)

單例模式實現方式&#xff1a;懶漢式、餓漢式、雙重檢查、枚舉、靜態內部類&#xff1b; 懶漢式&#xff1a; /*** 懶漢式單例模式* author: 小手WA涼* create: 2024-07-06*/ public class LazySingleton implements Serializable {private static LazySingleton lazySinglet…

對BSV區塊鏈的曼達拉網絡通俗易懂的解釋

??發表時間&#xff1a;2023年6月15日 BSV區塊鏈正在引入“曼達拉”升級&#xff0c;使BSV區塊鏈網絡的拓撲結構能夠適配Teranode&#xff0c;適配這個可以大幅擴容的節點軟件。BSV區塊鏈上曼達拉網絡的概念并不會改變整個系統的核心規則&#xff1b;相反&#xff0c;它能夠引…

為什么https比http更安全

讀完本文&#xff0c;希望你能明白&#xff1a; HTTP通信存在什么問題HTTPS如何改進HTTP存在那些問題HTTPS工作原理是什么 一、什么是HTTPS HTTPS是在HTTP上建立SSL加密層&#xff0c;并對傳輸數據進行加密&#xff0c;是HTTP協議的安全版。現在它被廣泛用于萬維網上安全敏感…

【qt】如何獲取本機的IP地址?

需要用到這個類QHostInfo和pro里面添加network模塊 用這個類的靜態函數forName()來獲取該主機名的信息 返回的就是這個類 這個QHostInfo類就包括主機的IP地址信息 用靜態函數addresses()來獲取 返回的是一個QHostAddress的容器 QList<QHostAddress>addrList hostIn…

Laravel隊列機制深度解析:異步任務處理的高效之道

Laravel隊列機制深度解析&#xff1a;異步任務處理的高效之道 Laravel的隊列系統是一個強大的工具&#xff0c;用于執行后臺任務和異步處理。它允許開發者將耗時的任務&#xff0c;如發送郵件、處理圖片等&#xff0c;放入隊列中&#xff0c;然后由后臺工作進程異步執行。本文…

Docker 鏡像移動或復制到另一臺服務器

在實際的開發和部署過程中&#xff0c;我們可能需要將 Docker 鏡像從一臺服務器移動或復制到另一臺服務器。本文將詳細介紹如何實現這一操作&#xff0c;幫助你更好地管理和遷移 Docker 鏡像。 一、使用 docker save 和 docker load 命令 docker save 和 docker load 是 Dock…

課題申報書中要用的思路圖(技術路線圖)30張,超高清!

最近在弄課題申報書的時候&#xff0c;需要畫“技術路線圖”&#xff1b;和小伙伴們探討才發現很多人居然不會畫這種圖&#xff0c;還有很多人在Word里面一點一點拼湊…… 我給大家收集了網上非常熱門的30張“技術路線圖”&#xff0c;但網上流傳的都太模糊了&#xff0c;想看…

KBPC3506-ASEMI儲能專用整流橋KBPC3506

編輯&#xff1a;ll KBPC3506-ASEMI儲能專用整流橋KBPC3506 型號&#xff1a;KBPC3506 品牌&#xff1a;ASEMI 封裝&#xff1a;KBPC-4 正向電流&#xff08;Id&#xff09;&#xff1a;35A 反向耐壓&#xff08;VRRM&#xff09;&#xff1a;600V 正向浪涌電流&#xf…

基于RK3588的8路攝像頭實時全景拼接

基于RK3588的8路攝像頭實時全景拼接 輸入&#xff1a;2路csi轉8路mpi的ahd攝像頭&#xff0c;分辨率1920 * 1080 8路拼接結果&#xff1a; 6路拼接結果&#xff1a; UI界面&#xff1a; UI節目設計原理

SpringBoot新手快速入門系列教程一:window上編程環境安裝和配置

首先編譯器&#xff0c;建議各位不要去嘗試AndroidStudio和VisualStudio來做SpringBoot項目。乖乖的直接下載最新版即可 https://www.jetbrains.com.cn/idea/ 當然這是一個收費的IDE&#xff0c;想要便宜可以想辦法去某寶買授權&#xff0c;僅供學習參考用&#xff01;賺了錢…