基於關聯容器map與multimap的快速檢索

2021-10-09 14:18:11 字數 3509 閱讀 7805

使用multimap查詢多個元素

總結結果驗證

說到紅黑樹大家肯定很陌生,但是,有一種資料結構肯定聽說過,那就是二叉樹,二叉樹這種結構很簡單,大家肯定都懂,凡是每個節點都最多有兩個叉的樹,就叫二叉樹。實質上,紅黑樹是一種特殊的二叉查詢樹,特殊之處就在它是一種平衡的二叉查詢樹,平衡兩字說起來容易,做起來可就難了,每次有元素做增減時,都要做到完全自動的平衡。儘管這樣,我查資料發現其實紅黑樹也不是一種完美的平衡二叉樹。

有想詳細了解紅黑樹的可以參考如下鏈結

新增鏈結描述

在物件導向的程式設計中,提出了容器的概念。c++提供了很多的模板類可供選擇,這些模組類為容器處理提供的支撐。如果經常使用c語言程式設計,當接觸到模組、容器時真的感覺太爽了,好多在c中難以解決的問題,在c++中輕鬆的很,例如你使用容器甚至都可以不用考慮記憶體分配的問題。總之,就一句話,真**的香。

容器分為順序容器與關聯容器。我們接下來要說到的map以及multimap都是關聯容器。關聯容器相較於順序容器是一種非線性結構,並且以鍵值的方式來儲存資料。

map的複雜度是 o(logn)(2為底),也就是說,原來需要迴圈15000次的才能查到的資料,現在最差只需比較十多次就能完成,檢索效率是極其高的。但是,map是一對一的,也就是說,乙個key對應乙個value,無法做到一對多。

其實map本身不是很難,用起來很方便,但是設計合適的key—value倒是一件挺需要琢磨的事,尤其是在乙個已經成熟的系統中,加入map的時候,需要很好的把系統框架理清楚,你才能清楚的知道,什麼樣的key—value最合適。

我設計的key是模組id,因為在系統中,模組id是唯一的,然後value是模組在記憶體中的指標。

首先包含如下標頭檔案

#include

在.**件中宣告乙個全域性的變數

extern std::map<

unsigned

int,

void

*> mapnetio;

在.cpp中定義

std::map<

unsigned

int,

void

*> mapnetio;

插入的方法其實比較多,我知道的至少有三種,我覺得最好用的還是使用insert函式插入pair資料。

mapnetio.

insert

(std::pair<

unsigned

int,

void

*>

(obj-

>par.source_model_id, arg)

);

insert之後就是終極目標,那就是查詢,或者說檢索。方法也有很多,最常用的無非就是利用map的下標或者迭代器的方式。

最簡單的就是使用下標,直接返回對應的value

mapnetio[key]
當然使用下標的方式是簡單,也存在危險。如果這個key是map中包含的,那麼沒有任何問題,如果在map中不存在那麼就很危險了。

可以使用如下兩個方式來檢查map中是否包含這個key

mapnetio.

count

(key)

mapnetio.

find

(key)

閱讀完map之後,你就會發現map不是應用於所有場合,當key—value是一對多時,那麼使用map是實現不了檢索多個value的,此時,就需要使用multimap,通過名字也可以看出,multimap就是乙個可以檢索多元的map。

首先包含標頭檔案,是的,你沒看錯,與map一樣

#include

在.**件中宣告乙個全域性的變數

extern std::multimap<

unsigned

int,

void

*> mapnetio;

在.cpp中定義

std::multimap<

unsigned

int,

void

*> mapnetio

;

插入的方法還是使用我覺得最方便的insert,這個和map沒啥區別

mapnetio.

insert

(std::pair<

unsigned

int,

void

*>

(obj-

>par.source_model_id, arg)

);

multimap的查詢方法比map稍微複雜一點點,因為在map中可以使用最簡單的方法,利用下標,但是multimap不行,此時,迭代器有了用武之地。

使用equal_range,檢索已知key的所有元素,它返回兩個迭代器,迭代器中封裝了pair物件。

auto iter = mapnetio.

equal_range

(source_model_id)

;//< 使用auto精簡**

auto iterbegin = iter.first;

//< 第乙個迭代器

auto iterend = iter.second;

//< 第二個迭代器

for(

; iterbegin != iterend; iterbegin++

)

auto的使用可以極大的簡化**,並且給對返回值不太清楚的函式,有了很好的解決方法。

其實,我使用的還不是簡單的multimap,因為我需要兩個key,因此,我使用的是multimap陣列.第乙個key是1~10的數字,第二個key是unsigned int,value是乙個指標。這個還是負責上位的松哥給我設計的,特此感謝松哥。

std::multimap<

unsigned

int,

void

*> mapnetio[11]

;

寫這篇文章的理由有兩個:

第一:我參與的專案中,我接替師兄負責下位部分,我們下位的**之前是跑在linux的系統中,是完完全全的c語言編寫的,因此,很多檢索使用的都是迴圈遍歷的方法。目前,我們的專案也開始轉戰windows平台,因此,我們的**還是希望能夠充分利用c++的優勢的,因此,查詢檢索使用了multimap。(ps:當然,實際情況是老師要求使用,必須使用)

第二:加入multimap之後,下位的基本框架還是保持不變的,也給師弟們留下一點資料,方便理解改動的**。

使用map前,採用迴圈遍歷查詢勇用時不超過29ms

使用multimap後,不超過3ms

map關聯容器

資料表記錄包含表索引和數值,請對錶索引相同的記錄進行合併,即將相同索引的數值進行求和運算,輸出按照key值公升序進行輸出。輸入描述 先輸入鍵值對的個數 然後輸入成對的index和value值,以空格隔開 輸出描述 輸出合併後的鍵值對 多行 輸入例子 4 0 10 2 1 23 4 輸出例子 0 3 ...

關聯容器map

map是一種key value關聯的容器,第乙個稱為關鍵字,只能在map中出現一次,第二個稱為關鍵字的值。特點 map是一類關聯式容器。它的特點是增加和刪除節點對迭代器的影響很小,除了那個操作節點,對其他的節點都沒有什麼影響。對於迭代器來說,可以修改實值,而不能修改key。1 map是 鍵 值 對的...

map容器即關聯容器

include string include map using namespace std intmain 資料 1.對映和多重對映以容器以鍵 值對 pair物件 的形式管理他們的元素,其元素按照 某種標準對鍵進行排列,預設標準為 排序時比較pair物件的資料成員first的值.相等則比較seco...