使用 庫建立關聯容器

2021-04-27 06:33:23 字數 3369 閱讀 9631

原文出處:use the library to create associative containers

摘要:當索引是整型,那麼將值與之關聯並不難,但如果資料的關聯值對是其它資料型別怎麼辦呢?庫具備乙個關聯容器,使用它可以很方便地關聯所有型別的資料對。本文將討論 庫的使用方法和技巧。

關聯式資料庫,科學計算應用以及基於web的系統常常需要類似 vector 的容器,其索引可以是如何資料型別,不一定是整數。這樣的容器叫關聯容器,或者 map。例如,目錄服務應用可以將私人姓名作為索引來儲存,**號碼作為其關聯的值:

directory["harry"]=8225687;// 插入 "harry" 並與他的**號碼關聯

iterator it=directory.find("harry");// 獲取 harry 的**號碼

其它關聯容器的應用還包括將 urls 對映到 ip 的 dns 伺服器,字典,庫存清單,工資表等等。那麼如何突破整型索引的侷限,實現用其它資料型別作為索引的關聯容器呢?答案是:使用 庫建立和處理關聯容器。

pair 和 map

最近的一篇文章中,我介紹了 tuple 的概念,它是不同型別元素的集合。在這篇文章中,有乙個內容沒有提到,那就是 c++98 標準庫已經具備乙個特殊的 tuple 型別——pair。它將鍵值(也就是第乙個元素)與某個值(第二個值)關聯。例如:

#include //definition of pair

#include pair prof_and_course("jones", "syntax");

pair symbolic_const (0, "false");

標準庫還定義了乙個輔助函式,方便 pair 型別的建立:

string prof;

string course;

make_pair(prof,course);//returns pair

第一步:構造和初始化乙個 map 物件

假設你正在開發乙個位址簿程式,位址簿包含姓名和 e-mail 位址。類模板 map 在 中定義i,它是乙個使用型別對的關聯容器,第乙個元素是索引,第二個元素是關聯的值。使用方法如下:

#include map addresses;
為了新增元素,使用下標算符:

addresses["paul w."]="[email protected]";
這裡,串「paul w.」是索引或鍵值,「[email protected]」是其關聯的值。如果該 map 已經包含了此鍵值,那麼當前所關聯的值不會改變: 

addresses["paul w."]=

"[email protected]"; // 不起作用

第二步:搜尋

在不插入元素的情況下,如果你想檢查某個元素是否存在,可以使用 find()成員函式。find()有兩個過載的版本:

iterator find(const key_type& k);

const_iterator find(const key_type& k) const;

通常,用 typedef 可以使**更可讀一些:

typedef map ::const_iterator cit;

cit cit=addresses.find("paul w.");

if (cit==addresses.end())

cout << "sorry, no such key" << endl;

else

cout << cit->first << ''/t'' << cit->second << endl;

表示式中 cit->first 和 cit->second 分別返回鍵值及其關聯的值。

第三步:元素遍歷

現在讓我們看乙個更現實的情況。假設你正在經營一家旅行社,每乙個**做一單業務都可以獲得獎金。這些**的資訊儲存在某個檔案中,其格式如下:

bob 35

bob 90

jane 80.25

sue 100

jane 65.5

你的應用程式必須彙總所有**的獎金並將每個**的獎金總數顯示出來.首先,建立乙個 map,然後讀取該資料檔案:

map bonuses;

string agent;

double bonus=0;

ifstream bonusfile("bonuses.dat");

if(!bonusfile)

while (bonusfile >> agent >> bonus)

不管理相不相信,就這麼簡單!且讓我們來分析一下該迴圈。開啟資料檔案之後,while 迴圈讀取每個值對,並將其存入 agent 和 bouns 物件。接著,它將 agent 和 bouns 插入到該 map。此處的關鍵技巧是:如果鍵值(agent)已經存在,那麼 += 操作符便將最新讀取的 bouns 累加到儲存在 map 中當前的 bouns 中。因為表示式:

map[key]
返回與鍵值關聯的值。當過載的 += 操作符被呼叫時,該值便被累加到新讀取的 bouns 中。最後累加的和覆蓋 map 中舊的關聯值。記住:當你使用下標算符機制時,純粹的賦值操作並不會改寫現有的值,只有過載的 += 才這麼做。

幸運的是,map 並不包含乙個必須要初始化的鍵值,表示式:

map[key]
返回預設的初始化 t,而 t 在上述例子中是 double 型別。預設的初始值為 0。至此,map 包含**及其獎金彙總值對。下面的迴圈用來顯示這些值對,輸出如圖一所示:

for(cit p=bonuses.begin(); p!=bonuses.end(); ++p)

{ cout << p->first <<''/t'' << p->second <

圖一 **獎金匯總數

雜湊的關聯容器

標準庫目前還不提供雜湊關聯容器。這種容器可以大大改進效能,因為它們使用雜湊演算法從原來的字串索引派生短鍵值。但是,許多 ides 提供非標準雜湊容器擴充套件。值得慶幸的是,新的 c++0x 標準彌補了這一點,在 c++ 中新增了一組雜湊容器和與之相關的演算法。

作者簡介

danny kalev是一名通過認證的系統分析師,專攻 c++ 和形式語言理論的軟體工程師。1997 年到 2000 年期間,他是 c++ 標準委員會成員。最近他以優異成績完成了他在普通語言學研究方面的碩士**。 業餘時間他喜歡聽古典**,閱讀維多利亞時期的文學作品,研究 hittite、basque 和 irish gaelic 這樣的自然語言。其它興趣包括考古和地理。danny 時常到一些 c++ 論壇並定期為不同的 c++ **和雜誌撰寫文章。他還在教育機構講授程式語言和應用語言課程。

運用map庫建立關聯容器

原文出處 use the library to create associative containers 摘要 當索引是整型,那麼將值與之關聯並不難,但如果資料的關聯值對是其它資料型別怎麼辦呢?庫具備乙個關聯容器,使用它可以很方便地關聯所有型別的資料對。本文將討論 庫的使用方法和技巧。關聯式資料庫...

11 1使用關聯容器

map是stl的乙個容器,和set一樣,map也是一種關聯式容器。它提供一對一 其中第乙個可以稱為關鍵字,每個關鍵字只能在map中出現一次,第二個可能稱為該關鍵字的值 的資料處理能力,由於這個特性,有助於我們處理一對一資料。map內部是自建一顆紅黑樹 一種非嚴格意義上的平衡二叉樹 這顆樹具有對資料自...

C 標準庫關聯容器

1 關聯容器定義 儲存物件集合的型別,支援通過鍵的高效訪問。和順序容器的本質差別在於 順序容器通過元素在容器中的位置順序儲存和訪問元素,而關聯容器卻是依靠鍵。map和set是兩個基本的關聯容器型別,map以鍵值對的形式組織儲存元素,而set僅儲存鍵。2,pair型別 在utility標頭檔案中定義 ...