1. 程式人生 > 其它 >C++STL標準庫學習筆記(六)multimap

C++STL標準庫學習筆記(六)multimap

這篇文章簡單介紹了STL標準庫中mulitmap的使用

前言:

在這個筆記中,我把大多數程式碼都加了註釋,我的一些想法和註解用藍色字型標記了出來,重點和需要關注的地方用紅色字型標記了出來。

在這一篇文章中,我們主要介紹multimap的用法和應用

1.1multimap的用法

使用時需要#include<map>

multimap容器中的元素,都是pair形式的,這玩意也是排序容器。

  mulitmap<T1,T2> mp;

則mp裡的元素都是如下型別:

1 struct 
2 {
3   T1 first;//關鍵字
4   T2 second;//
5 };

multimap中的元素按照first排序,並可以按first進行查詢

multimap具有自動排序的功能,它的底層和set一樣是採用平衡樹實現的,而multimap中的每個節點儲存的是一對資訊,包括一個鍵和一個值。

而set中的每個節點儲存的是一個資訊,只有一個鍵,但是每個鍵值也是唯一的。set表示的是集合的概念。

預設的排序規則是“a.first < b.first”為true,則a排在b前面。就是說預設就是這樣排序。

1.2 multimap的應用

一個學生成績錄入和查詢系統,接受以下兩種輸入:

Add name id score

Query score

name是個不超過16字元的字串,中間沒有空格,代表學生姓名。Id是個整數,代表學號。score是個整數,代表分數。學號不會重複,分數和姓名都可能重複。

兩種輸入交替出現。第一種輸入表示要新增一個學生的資訊,碰到這種輸入,就記下學生的姓名、id和分數。第二種輸入表示要查詢,碰到這種輸入,就輸出已有記錄中分數比score低的最高分獲得者的姓名、學號和分數。如果有多個學生都滿足條件,就輸出學號最大的那個學生的資訊。如果找不到滿足條件的學生,則輸出“nobody”

程式如下:

  1 /*
  2 一個學生成績錄入和查詢系統,接受以下兩種輸入:
  3 Add name id score
  4 Query score
  5 name是個不超過16字元的字串,中間沒有空格,代表學生姓名。Id是個整數,代表學號。score是個整數,代表分數。學號不會重複,分數和姓名都可能重複。
6 兩種輸入交替出現。第一種輸入表示要新增一個學生的資訊,碰到這種輸入,就記下學生的姓名、id和分數。 7 第二種輸入表示要查詢,碰到這種輸入,就輸出已有記錄中分數比score低的最高分獲得者的姓名、學號和分數。 8 如果有多個學生都滿足條件,就輸出學號最大的那個學生的資訊。如果找不到滿足條件的學生,則輸出“nobody” 9 */ 10 /* 11 輸入樣例: 12 Add Jack 12 78 13 Query 78 14 Query 81 15 Add Percy 9 81 16 Add marry 8 81 17 Query 82 18 Add Tom 11 79 19 Query 80 20 Query 81 21 輸出樣例: 22 Nobody 23 Jack 12 78 24 Percy 9 81 25 Tom 11 79 26 Tom 11 79 27 */ 28 #include<iostream> 29 #include<map> 30 #include<cstring> 31 using namespace std; 32 struct StudentInfo 33 { 34 int id; 35 char name[20]; 36 }; 37 struct Student 38 { 39 int score; 40 StudentInfo info; 41 }; 42 typedef multimap<int,StudentInfo> MAP_STD; 43 //這裡int和studentinfo是和結構體裡面的int,info相對應的 44 //此後 MAP_STD 等價於 multimap<int,StudentInfo> 45 //typedef int* PINT; 46 //則此後 PINT 等價於 int*。即 PINT p; 等價於 int* p 47 48 int main(int argc, char const *argv[]) 49 { 50 MAP_STD mp; 51 Student st; 52 char cmd[20]; 53 while (cin >> cmd) 54 { 55 if (cmd[0] == 'A') 56 { 57 cin >> st.info.name >> st.info.id >> st.score; 58 mp.insert(make_pair(st.score,st.info)); 59 } 60 //make_pair生成一個pair<int,StudentInfo>變數 61 //其first等於st.score, second等於st.info 62 else if (cmd[0] == 'Q') 63 { 64 int score; 65 cin >> score; 66 MAP_STD::iterator p = mp.lower_bound(score);//關鍵字查詢 67 if (p != mp.begin())//找到了 68 { 69 --p; 70 score = p->first;//比要查詢分數低的最高分 71 MAP_STD::iterator maxp = p; 72 int maxId = p->second.id; 73 for (; p != mp.begin() && p->first == score; --p) 74 {//遍歷所有成績和score相等的學生,開始比較學號的差別 75 if (p->second.id > maxId) 76 { 77 maxp = p; 78 maxId = p->second.id; 79 } 80 81 } 82 if (p->first == score) 83 {//如果上面迴圈是因為 p==mp.begin() 而終止,則p指向的元素還要處理 84 if (p->second.id > maxId) 85 { 86 maxp = p; 87 maxId = p->second.id; 88 } 89 } 90 cout<<maxp->second.name<<" "<<maxp->second.id<<" "<<maxp->first<<endl; 91 }//lower_bound的結果就是begin,說明沒人分數比查詢分數低 92 else 93 { 94 cout<<"Nobody"<<endl; 95 } 96 } 97 98 } 99 100 return 0; 101 }
樣例

老樣子,強調一下程式中出現的重點:

1、make_pair(st.score,st.info)

make_pair產生一個pair<int,StudentInfo>變數,相當於結構體轉換成pair了。

2、mp.insert(make_pair(st.score,st.info))

插入的是pair型別。

3、mp.lower_bound(score)

lower_bound的返回值是某個鍵的迭代器(若該鍵不存在,則返回挨著這個鍵的下一個鍵的迭代器),這裡返回的是成績大於等於score的迭代器。

後記:

在做這一節的筆記的時候因為好奇去看了很多大佬的部落格,一些內容也是由他們的部落格補充而來,看完之後感覺自己太菜,確實差距太大,感覺自己還有很長很長很長很長很長很長的路要走。只不過不積跬步無以至千里,不積小流無以成江海,如果因為他們太厲害而停止學習的話,那又有什麼意思呢,不嘗試一下還不知道行不行呢。以後等我完全學會了,再整理完整的資料發部落格。

感謝大家讀到這裡,希望大家能在程式碼的海洋中找到自己的快樂,下個部落格再見。