一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - C/C++ - C++哈希應用的位圖和布隆過濾器

C++哈希應用的位圖和布隆過濾器

2021-12-30 15:03森明幫大于黑虎幫 C/C++

這篇文章主要介紹了C++哈希應用的位圖和布隆過濾器的相關資料,文章內容多以列舉試題的方式講解,感興趣的朋友可以參考下面文章內容

C++哈希應用的位圖和布隆過濾器

一、位圖

1.位圖的概念

所謂位圖,就是用每一位來存放某種狀態,適用于海量數據,數據無重復的場景。通常是用來判斷某個數據存不存在的。

2.位圖的面試題

給40億個不重復的無符號整數,沒排過序。給一個無符號整數,如何快速判斷一個數是否在這40億個數中。【騰訊】

  • 遍歷,時間復雜度O(N)。
  • 排序(O(NlogN)),利用二分查找: logN。
  • 位圖解決。

數據是否在給定的整形數據中,結果是在或者不在,剛好是兩種狀態,那么可以使用一個二進制比特位來代表數據是否存在的信息,如果二進制比特位為1,代表存在,為0代表不存在。比如:

C++哈希應用的位圖和布隆過濾器

3.位圖的實現

C++哈希應用的位圖和布隆過濾器

#include<iostream>
#include<vector>
#include<math.h>
namespace yyw
{
class bitset
{
public:
bitset(size_t N)
{
 _bits.resize(N / 32 + 1, 0);
 _num = 0;
}

//將x位的比特位設置為1
void set(size_t x)
{
 size_t index = x / 32;           //映射出x在第幾個整形
 size_t pos = x % 32;             //映射出x在整形的第幾個位置
 _bits[index] |= (1 << pos);
 _num++;
}

//將x位的比特位設置為0
void reset(size_t x)
{
 size_t index = x / 32;
 size_t pos = x % 32;
 _bits[index] &= ~(1 << pos);
 _num--;
}

//判斷x位是否在不在
bool test(size_t x)
{
 size_t index = x / 32;
 size_t pos = x % 32;

 return _bits[index] & (1 << pos);
}

//位圖中比特位的總個數
size_t size()
{
 return _num;
}
private:
std::vector<int> _bits;
size_t _num;            //映射存儲了多少個數據
};

void tes_bitset()
{
bitset bs(100);
bs.set(99);
bs.set(98);
bs.set(97);

bs.set(10);

for (size_t i = 0; i < 100; i++)
{
 printf("[%d]:%d\n", i, bs.test(i));
}

//40億個數據,判斷某個數是否在數據中
//bs.reset(-1);
//bs.reset(pow(2, 32));
}
}

4.位圖的應用

  • 快速查找某個整形數據是否在一個集合中。
  • 排序。
  • 求兩個集合的交集、并集等。
  • 操作系統中磁盤塊標記。

二、布隆過濾器

1.布隆過濾器的提出

C++哈希應用的位圖和布隆過濾器

我們在使用新聞客戶端看新聞時,它會給我們不停地推薦新的內容,它每次推薦時要去重,去掉那些已經看過的內容。問題來了,新聞客戶端推薦系統如何實現推送去重的? 用服務器記錄了用戶看過的所有歷史記錄,當推薦系統推薦新聞時會從每個用戶的歷史記錄里進行篩選,過濾掉那些已經存在的記錄。 如何快速查找呢?

  • 用哈希表存儲用戶記錄,缺點:浪費空間。
  • 用位圖存儲用戶記錄,缺點:不能處理哈希沖突。
  • 將哈希與位圖結合,即布隆過濾器。

2.布隆過濾器的概念

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

3.布隆過濾器的插入

布隆過濾器底層是位圖:

C++哈希應用的位圖和布隆過濾器

struct HashStr1
{
//BKDR1
size_t operator()(const std::string& str)
{
 size_t hash = 0;
 for (size_t i = 0; i < str.size(); i++)
 {
  hash *= 131;
  hash += str[i];
 }
 return hash;
}
};

struct HashStr2
{
//RSHash
size_t operator()(const std::string& str)
{
 size_t hash = 0;
 size_t magic = 63689; //魔數
 for (size_t i = 0; i < str.size();i++)
 {
  hash *= magic;
  hash += str[i];
  magic *= 378551;
 }
 return hash;
}
};

struct HashStr3
{
//SDBHash
size_t operator()(const std::string& str)
{
 size_t hash = 0;
 for (size_t i = 0; i < str.size(); i++)
 {
  hash *= 65599;
  hash += str[i];
 }
 return hash;
}
};

//假設布隆過濾器元素類型為K,如果類型為K要自己配置仿函數
template<class K,class Hash1=HashStr1,class Hash2=HashStr2,class Hash3=HashStr3>
class bloomfilter
{
public:
bloomfilter(size_t num)
 :_bs(5*num)
 , _N(5*num)
{

}
void set(const K& key)
{
 size_t index1 = Hash1()(key) % _N;
 size_t index2 = Hash2()(key) % _N;
 size_t index3 = Hash3()(key) % _N;

 _bs.set(index1);   //三個位置都設置為1
 _bs.set(index2);
 _bs.set(index3);
}
}

4.布隆過濾器的查找

布隆過濾器的思想是將一個元素用多個哈希函數映射到一個位圖中,因此被映射到的位置的比特位一定為1。所以可以按照以下方式進行查找:分別計算每個哈希值對應的比特位置存儲的是否為零,只要有一個為零,代表該元素一定不在哈希表中,否則可能在哈希表中。

bool test(const K& key)
{
 size_t index1 = Hash1()(key) % _N;
 if (_bs.test(index1) == false)
 {
  return false;
 }

 size_t index2 = Hash1()(key) % _N;
 if (_bs.test(index2) == false)
 {
  return false;
 }

 size_t index3 = Hash3()(key) % _N;
 if (_bs.test(index3) == false)
 {
  return false;
 }

 return true;  //但是這里也不一定是真的在,還有可能存在誤判

 //判斷不在是正確的,判斷在可能存在誤判
}

注意:布隆過濾器如果說某個元素不存在時,該元素一定不存在,如果該元素存在時,該元素可能存在,因為有些哈希函數存在一定的誤判。

比如:在布隆過濾器中查找"alibaba"時,假設3個哈希函數計算的哈希值為:1、3、7,剛好和其他元素的比特位重疊,此時布隆過濾器告訴該元素存在,但實該元素是不存在的。

5.布隆過濾器的刪除

布隆過濾器不能直接支持刪除工作,因為在刪除一個元素時,可能會影響其他元素。

比如:刪除上圖中"tencent"元素,如果直接將該元素所對應的二進制比特位置0,“baidu”元素也被刪除了,因為這兩個元素在多個哈希函數計算出的比特位上剛好有重疊。

C++哈希應用的位圖和布隆過濾器

一種支持刪除的方法:將布隆過濾器中的每個比特位擴展成一個小的計數器,插入元素時給k個計數器(k個哈希函數計算出的哈希地址)加一,刪除元素時,給k個計數器減一,通過多占用幾倍存儲空間的代價來增加刪除操作。

缺陷:

  • 無法確認元素是否真正在布隆過濾器中。
  • 存在計數回繞。

6.布隆過濾器的優點和缺點

  • 優點:節省空間,高效,可以標注存儲任意類型
  • 缺點;存在誤判,不支持刪除

位圖

  • 優點:節省空間
  • 缺點:只能處理整形

三、海量數據面試題

1.哈希切割

給一個超過100G大小的log file, log中存著IP地址, 設計算法找到出現次數最多的IP地址? 與上題條件相同,如何找到top K的IP?如何直接用Linux系統命令實現?

C++哈希應用的位圖和布隆過濾器

2.位圖應用

①給定100億個整數,設計算法找到只出現一次的整數?

C++哈希應用的位圖和布隆過濾器

②給兩個文件,分別有100億個整數,我們只有1G內存,如何找到兩個文件交集?

  • 方案1:將其中一個文件1的整數映射到一個位圖中,讀取另外一個文件2中的整數,判斷在在不在位圖,在就是交集。消耗50OM內存
  • 方案2:將文件1的整數映射到位圖1中,將文件2的整數映射到位圖2中,然后將兩個位圖中的數按位與。與之后為l1的位就是交集。消耗內存1G。

③位圖應用變形:1個文件有100億個int,1G內存,設計算法找到出現次數不超過2次的所有整數?

  • 本題跟上面的第1題思路是一樣的
  • 本題找的不超過2次的,也就是要找出現1次和2次的
  • 本題還是用兩個位表示一個數,分為出現0次00表示,出現1次的01表示D出現2次的10表示出現3次及3次以上的用11表示

3.布隆過濾器

①給兩個文件,分別有100億個query,我們只有1G內存,如何找到兩個文件交集?分別給出精確算法和近似算法?

C++哈希應用的位圖和布隆過濾器

②如何擴展BloomFilter使得它支持刪除元素的操作?

C++哈希應用的位圖和布隆過濾器

到此這篇關于C++哈希應用的位圖和布隆過濾器的文章就介紹到這了,更多相關C++哈希應用位圖與布隆過濾器內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://blog.csdn.net/qq_44918090/article/details/120000787

延伸 · 閱讀

精彩推薦
  • C/C++深入理解goto語句的替代實現方式分析

    深入理解goto語句的替代實現方式分析

    本篇文章是對goto語句的替代實現方式進行了詳細的分析介紹,需要的朋友參考下...

    C語言教程網7342020-12-03
  • C/C++c++ 單線程實現同時監聽多個端口

    c++ 單線程實現同時監聽多個端口

    這篇文章主要介紹了c++ 單線程實現同時監聽多個端口的方法,幫助大家更好的理解和學習使用c++,感興趣的朋友可以了解下...

    源之緣11542021-10-27
  • C/C++C++之重載 重定義與重寫用法詳解

    C++之重載 重定義與重寫用法詳解

    這篇文章主要介紹了C++之重載 重定義與重寫用法詳解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下...

    青山的青6062022-01-04
  • C/C++學習C++編程的必備軟件

    學習C++編程的必備軟件

    本文給大家分享的是作者在學習使用C++進行編程的時候所用到的一些常用的軟件,這里推薦給大家...

    謝恩銘10102021-05-08
  • C/C++C/C++經典實例之模擬計算器示例代碼

    C/C++經典實例之模擬計算器示例代碼

    最近在看到的一個需求,本以為比較簡單,但花了不少時間,所以下面這篇文章主要給大家介紹了關于C/C++經典實例之模擬計算器的相關資料,文中通過示...

    jia150610152021-06-07
  • C/C++C語言實現電腦關機程序

    C語言實現電腦關機程序

    這篇文章主要為大家詳細介紹了C語言實現電腦關機程序,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    xiaocaidayong8482021-08-20
  • C/C++C語言中炫酷的文件操作實例詳解

    C語言中炫酷的文件操作實例詳解

    內存中的數據都是暫時的,當程序結束時,它們都將丟失,為了永久性的保存大量的數據,C語言提供了對文件的操作,這篇文章主要給大家介紹了關于C語言中文件...

    針眼_6702022-01-24
  • C/C++詳解c語言中的 strcpy和strncpy字符串函數使用

    詳解c語言中的 strcpy和strncpy字符串函數使用

    strcpy 和strcnpy函數是字符串復制函數。接下來通過本文給大家介紹c語言中的strcpy和strncpy字符串函數使用,感興趣的朋友跟隨小編要求看看吧...

    spring-go5642021-07-02
主站蜘蛛池模板: 欧美福利在线播放 | videojapan日本孕交孕 | 国产一级大片免费看 | 日本精品欧洲www | 日本天堂视频 | 91精品国产高清久久久久 | 亚洲欧美日韩中文字幕网址 | 男人天堂bt| 99久久精品免费看国产一区 | 2019年国产不卡在线刷新 | 免费高清视频免费观看 | 毛片在线观看网站 | 国产成人福利色视频 | 1024国产高清精品推荐 | 成人国产网站v片免费观看 成人国产精品视频 | 边打电话边操 | 欧美国产日韩综合 | 精品一久久香蕉国产二月 | 免费欧美一级片 | 亚洲同性男男gay1069 | 国产成人综合亚洲一区 | 欧美高清在线精品一区 | 娇小老少配xxxxx性视频 | 粉嫩国产14xxxxx0000 | 亚洲热影院 | 情乱奶水欲| 国产精品天天看特色大片不卡 | 好姑娘在线观看完整版免费 | 国产成人综合亚洲一区 | 非洲黑女人性xxxx | 99久久精品免费精品国产 | 精品欧美小视频在线观看 | 欧美在线视频一区二区 | 999久久久免费精品国产牛牛 | 天码毛片一区二区三区入口 | 91成人免费观看 | 亚洲日日做天天做日日谢 | 无套插入| chinese男同志videos | www.青青操| 亚洲国产成人久久综合一 |