數據結構 之 【位圖的簡介】

目錄

1.位圖的引入

2.位圖概念

3.位圖的實現

3.1前提準備

3.2set

3.3reset

3.4test

4.位圖的應用


1.位圖的引入

給40億個不重復的無符號整數,沒排過序

再給一個無符號整數,如何快速判斷這個無符號整數是否在 這40億個數中

首先,一個無符號整數占4個字節,40億個無符號整數占160億字節

其次,1GB = 1024MB = 1024*1024KB = 1024*1024*1024Byte 約等于 10億+ 字節

那么40億個無符號整數需要約16G的內存,超出普通計算機的容量,更別提

使用哈希(指針等額外開銷)、排序后二分查找(內存壓力未解決)判斷,

解決方法:使用位圖標記

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

2.位圖概念

位圖就是用比特位表示一個數據的狀態信息,適用于海量數據,數據無重復的場景。通常是用來判斷某個數據存不存在的

位圖就是將數據與數據在位圖中對應的比特位進行了一一對應,是哈希的一種變形

3.位圖的實現

用字節進行位運算,我們可以操縱某一個比特位為0或者為1

因為位運算操作的是數據的二進制位模式,而非內存中的字節順序,所以我們不必關注端序

只是在畫圖的時候需要關注一下端序(大小端)

3.1前提準備

#pragma once
#include<vector>
namespace dfq
{template<size_t N>class bitset{public:bitset(){_a.resize(N / 32 + 1);}private:vector<int> _a;};
}
(1)C++庫里面有 bitset 的實現,創建命名空間避免命名沖突
(1)非類型模板參數N表示要開多大的空間
(1)使用一個整型或者char類型的數組,通過字節位運算操縱比特位
(1)構造函數,向上取整開空間

3.2set

//將x映射的那個位置變為1
void set(size_t x)
{size_t i = x / 32;//i標識x映射到_a的第幾個位置size_t j = x % 32;//j標識x映射到4個字節中的哪一個位置_a[i] |= (1 << j);
}

(1)??i 標識x映射到_a的第幾個位置
(2)?j 標識x映射到4個字節中的哪一個位置

(3) 數組中對應數據的對應二進制位變為1

| 或運算的特點,有1為1,0與其他數進行或運算等于其他數本身
<< 左移運算符的特點,數據的二進制為向高位移動,左邊舍棄,右邊補0

......... 0 ...........   == _a[i]00000000001000000000000   == 1 << j

3.3reset

//將x映射的那個位置變為0
void reset(size_t x)
{size_t i = x / 32;//i標識x映射到_a的第幾個位置size_t j = x % 32;//j標識x映射到4個字節中的哪一個位置_a[i] &= ~(1 << j);
}

(1) 數組中對應數據的對應二進制位變為0

& 與運算的特點,有0為0,1與其他數進行與運算等于其他數本身
<< 左移運算符的特點,數據的二進制為向高位移動,左邊舍棄,右邊補0

~ 按位取反運算特點,數據的二進制位 1 變 0,0變1

......... 1 ...........   == _a[i]00000000001000000000000   == 1 << j11111111110111111111111   == ~(1 << j)

3.4test

bool test(size_t x)
{size_t i = x / 32;//i標識x映射到_a的第幾個位置size_t j = x % 32;//j標識x映射到4個字節中的哪一個位置return _a[i] & (1 << j);
}

_a[i] & (1 << j) 的意思是:

數據存在,數組中對應數據的對應比特位為1,表達式不為0,為真

數據不存在,數組中對應數據的對應比特位為0,表達式為0,為假

4.位圖的應用

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

(1)使用兩個位圖 bs1、bs2 (根據范圍開空間)

(2)從文件中讀取數據,調用set函數進行標記,標記原理及規則如下:

bs1、bs2對應的比特位一個有 00、01、10、11四種情況,我們取前面三種

  • 初始條件下,bs1、bs2比特位均為0
  • 數據第一次出現(!_bs1.test(x) && !_bs2.test(x)),bs2.set(x)
  • 數據第二次出現(!_bs1.test(x) && _bs2.test(x)),bs1.set(x);bs2.reset(x)
  • 三次以上就不進行統計了

(3)bs1、bs2對應的比特位組合為01的數就是只出現一次的整數

template<size_t N>
class twobitset
{
public://x映射的那個值變為1void set(size_t x){//00 -> 01if (!_bs1.test(x) && !_bs2.test(x))_bs2.set(x);//01 -> 10else if (!_bs1.test(x) && _bs2.test(x)){_bs1.set(x);_bs2.reset(x);}//10 就不變了}//檢測x是否只存在一次bool is_once(size_t x){return !_bs1.test(x) && _bs2.test(x);}private:bitset<N> _bs1;bitset<N> _bs2;
};

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

將兩個序列分別映射到兩個位圖上,對兩個位圖的每個字節進行按位與操作,結果為1 的比特位對應的數據的就是兩個序列的交集

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

與第一題的思路一致,使用兩個位圖統計次數,00、01、10、11

  • 初始條件下,bs1、bs2比特位均為0
  • 數據第一次出現(!_bs1.test(x) && !_bs2.test(x)),bs2.set(x)
  • 數據第二次出現(!_bs1.test(x) && _bs2.test(x)),bs1.set(x);bs2.reset(x)
  • 數據第三次出現(_bs1.test(x) && !_bs2.test(x)),bs2.set(x)
  • 四次以上就不進行統計了

總結位圖的應用:

1. 快速查找某個數據是否在一個集合中

2. 排序 + 去重

3. 求兩個集合的交集、并集等

4. 操作系統中磁盤塊標記

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

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

相關文章

[iOS] ViewController 的生命周期

文章目錄前言一、UIViewController 生命周期有關函數二、UIViewController 中函數的執行順序運行結果1.present和dismiss2.push和pop三、總結前言 UIViewController 是在 iOS 開發中一個非常重要的角色&#xff0c;他是 view 和 model 的橋梁&#xff0c;通過 UIViewControlle…

第30章 零售與電商AI應用

本章將深入探討人工智能在零售與電商領域的革命性應用。我們將從智能推薦系統、動態定價、庫存管理到創新的虛擬試衣間&#xff0c;全面解析AI如何重塑購物體驗和商業運營效率&#xff0c;并為每個關鍵技術點提供代碼實戰&#xff0c;幫助你掌握將AI應用于真實商業場景的能力。…

QT通過QModbusRtuSerialMaster讀寫電子秤數據實例

一、電子稱常用功能&#xff1a;稱重、清零、去皮&#xff1b;電子秤的通訊方式&#xff1a;Modbus通信、串口通信。二、QT讀寫電子秤軟件界面如下&#xff1a;三、核心代碼如下&#xff1a;.pro項目文件代碼&#xff1a;QT core gui serialbus serialport.h頭文件代碼#…

sqlmap常用命令

ZZHow(ZZHow1024) 一、掃描注入點 1.GET方法&#xff0c;給URL&#xff1a; #探測該url是否存在漏洞 python sqlmap.py -u "http://192.168.10.1/sqli/Less-1/?id1"#如果我們已經知道admin這里是注入點的話&#xff0c;可以在其后面加個*來讓sqlmap對其注入 python …

JVM如何排查OOM

當JVM&#xff08;Java虛擬機&#xff09;出現OOM&#xff08;OutOfMemoryError&#xff09;時&#xff0c;可以按照以下步驟和方法&#xff0c;用于幫助定位和解決JVM中的OOM問題1.查看異常堆棧信息查看異常堆棧信息&#xff08;StackTrace&#xff09;是定位問題的關鍵。OOM異…

存算一體芯片生態評估:從三星PIM到知存科技WTM2101

點擊 “AladdinEdu&#xff0c;同學們用得起的【H卡】算力平臺”&#xff0c;注冊即送-H卡級別算力&#xff0c;80G大顯存&#xff0c;按量計費&#xff0c;靈活彈性&#xff0c;頂級配置&#xff0c;學生更享專屬優惠。 引言&#xff1a;存算一體技術的崛起與意義 在傳統馮諾…

[數據結構] 棧 · Stack

一.棧 stack 1.概念 棧 : 一種特殊的線性表 , 其只允許再固定的一段進行插入和刪除元素操作 進行數據插入和刪除操作的一段稱為 棧頂 ; 另一端稱為棧底棧中的數據元素遵循 先進后出 原則(LIFO)壓棧 : 棧的插入操作叫做 進棧 或 壓棧 或 入棧 , 入數據在棧頂出棧 : 棧的刪除…

MySQL執行過程中如何選擇最佳的執行路徑

本篇文章介紹一個非常核心的數據庫問題。MySQL 選擇最佳執行路徑&#xff08;即“查詢優化”&#xff09;的過程是由其查詢優化器&#xff08;Query Optimizer&#xff09; 完成的。 簡單來說&#xff0c;優化器的目標是&#xff1a;在多種可能的執行方案中&#xff0c;選擇一個…

【設計模式】從游戲角度開始了解設計模式 --- 抽象工廠模式

永遠記住&#xff0c;你的存在是有意義的&#xff0c; 你很重要&#xff0c; 你是被愛著的&#xff0c; 而且你為這個世界帶來了無可取代的東西。 -- 麥克西 《男孩、鼴鼠、狐貍和馬》-- 從零開始了解設計模式抽象工廠模式抽象工廠模式 今天我們一起來探究抽象工廠模式&#x…

tensorflow.js 使用場景

TensorFlow.js (簡稱 TF.js) 是一個利用 WebGL 和 Node.js 在瀏覽器和服務器端進行機器學習模型訓練和部署(推理)的 JavaScript 庫。它的核心價值在于將機器學習的能力帶入了 Web 開發者和 JavaScript 生態的領域。 其主要應用場景可以分為以下幾大類: 一、在瀏覽器中直接進…

詳解mcp以及agen架構設計與實現

文章目錄1.MCP概念2.MCP服務端主要能力3.MCP技術生態4.MCP與Function call區別5.MCP生命周期6.MCP java SDK7.MCP應用場景8.基于springAIollma阿里qianwenmcp設計私有AIAgent應用實現9.AI java項目落地技術選型10.構建AI Agent四大模塊11.LLM(大模型)與MCP之間關系12.A2A、MCP、…

六級第一關——下樓梯

上目錄&#xff1a; 目錄 題目描述 輸入格式 輸出格式 輸入輸出樣例 說明/提示 一、DP的意義以及線性動規簡介 在一個困難的嵌套決策鏈中&#xff0c;決策出最優解。 二、動態規劃性質淺談 三、子序列問題 &#xff08;一&#xff09;一個序列中的最長上升子序列&am…

【Linux基礎】Linux系統配置IP詳解:從入門到精通

目錄 1 Linux網絡配置概述 2 網卡配置文件位置和命名規則 2.1 配置文件位置 2.2 網卡命名規則 2.3 配置文件命名示例 3 網卡配置文件詳解 3.1 主要參數說明 4 Linux系統配置IP步驟 4.1 DHCP動態配置 4.2 靜態IP配置 5 Linux網絡配置流程 5.1 網絡配置流程 5.2 網卡…

C語言sprintf的高效替代方案

C語言的sprintf和snprintf將變量格式化輸出到內存buffer&#xff0c;其功能強大&#xff0c;用起來很方便。但sprintf系列函數的運行效率低下&#xff0c;主要包括四方面的原因&#xff1a;格式字符串解析、變參處理、locale&#xff08;本地化&#xff09;支持和通用&#xff…

【知識堂】制造業與物流數字化全景圖:系統縮寫大全與專業名詞速查手冊

前言在制造業和物流行業的數字化轉型過程中&#xff0c;我們經常會接觸到大量的 系統縮寫&#xff08;如 ERP、MES、WMS…&#xff09;和 專業名詞&#xff08;如 AGV、BOM、LOT…&#xff09;。 這些縮寫往往讓剛入行的人“一頭霧水”&#xff0c;即使是有經驗的從業者&#x…

利用JSONCrack與cpolar提升數據可視化及跨團隊協作效率

文章目錄前言1. 在Linux上使用Docker安裝JSONCrack2. 安裝Cpolar內網穿透工具3. 配置JSON Crack界面公網地址4. 遠程訪問 JSONCrack 界面5. 固定 JSONCrack公網地址前言 JSONCrack 是一款功能強大的開源數據可視化工具&#xff0c;專為解析和展示復雜的 JSON、XML 等結構化數據…

CANoe入門之一 CANoe功能概述

01 CANoe功能概述 CANoe軟件在汽車電子領域被廣泛應用。 CANoe軟件的全稱是CAN Open Environment&#xff0c;它是一個專業的系統級總線和ECU仿真、分析、開發、測試工具。支持ECU或總線網絡開發從需求分析到系統實現的全過程&#xff0c;包括模型創建、仿真、測試、診斷及通信…

項目管理核心八項(軟件篇)

2025年09月11日23:50:33&#xff1a;進來常思&#xff0c;寫代碼也五六年了&#xff0c;后面的路該何去何從呢&#xff1f; 項目管理核心八項一、項目管理之“建立開發人員 backup 機制”二、待補充一、項目管理之“建立開發人員 backup 機制” “建立開發人員 backup 機制” 是…

springboot redisson 分布式鎖入門與實戰

Spring Boot3 Redisson 項目地址 https://gitee.com/supervol/loong-springboot-study &#xff08;記得給個start&#xff0c;感謝&#xff09; Redisson 介紹 在分布式系統中&#xff0c;多節點部署的應用對共享資源&#xff08;如數據庫記錄、緩存鍵、文件&#xff09;的…

使用 Tkinter + Requests 實現地理信息安全系統學習時長助手

?重磅&#xff01;盹貓的個人小站正式上線啦&#xff5e;誠邀各位技術大佬前來探秘&#xff01;? 這里有&#xff1a; 硬核技術干貨&#xff1a;編程技巧、開發經驗、踩坑指南&#xff0c;帶你解鎖技術新姿勢&#xff01;趣味開發日常&#xff1a;代碼背后的腦洞故事、工具…