• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            posts - 311, comments - 0, trackbacks - 0, articles - 0
              C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

            (搬運工)使用map 庫創建關聯容器

            Posted on 2010-11-24 20:00 點點滴滴 閱讀(166) 評論(0)  編輯 收藏 引用 所屬分類: 02 編程語言

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

            directory["Harry"]=8225687;// 插入 "Harry" 并與他的電話號碼關聯
            iterator it=directory.find("Harry");// 獲取 Harry 的電話號碼


              其它關聯容器的應用還包括將 URLs 映射到 IP 的 DNS 服務器,字典,庫存清單,工資表等等。那么如何突破整型索引的局限,實現用其它數據類型作為索引的關聯容器呢?答案是:使用 <map> 庫創建和處理關聯容器。

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

            #include <utility> //definition of pair
            #include <string>
            pair <string, string> prof_and_course("Jones", "Syntax");
            pair <int, string> symbolic_const (0, "false");


            標準庫還定義了一個輔助函數,方便 pair 類型的創建:

            string prof;
            string course;
            make_pair(prof,course);//returns pair <string,string>


            第一步:構造和初始化一個 map 對象
              假設你正在開發一個地址簿程序,地址簿包含姓名和 e-mail 地址。類模板 map 在 <map> 中定義i,它是一個使用類型對的關聯容器,第一個元素是索引,第二個元素是關聯的值。使用方法如下:

            #include <map>
            map 
            <stringstring> addresses;


            為了添加元素,使用下標算符:

            addresses["Paul W."]="paul@mail.com";


              這里,串“Paul W.”是索引或鍵值,“paul@mail.com”是其關聯的值。如果該 map 已經包含了此鍵值,那么當前所關聯的值不會改變: 

            addresses["Paul W."]= "newaddr@com.net"// 不起作用???我測試起作用



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

            iterator find(const key_type& k);
            const_iterator find(
            const key_type& k) const;



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

            typedef map <stringstring>::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 <stringdouble> bonuses;
            string agent;
            double bonus=0;
            ifstream bonusfile(
            "bonuses.dat");
            if(!bonusfile)
            {
            // 報告出錯信息并終止程序
            }
            while (bonusfile >> agent >> bonus)
            {
            bonuses[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 <<endl;
            }

             


            散列的關聯容器
              標準庫目前還不提供散列關聯容器。這種容器可以大大改進性能,因為它們使用散列算法從原來的字符串索引派生短鍵值。但是,許多 IDEs 提供非標準散列容器擴展。值得慶幸的是,新的 C++0X 標準彌補了這一點,在 C++ 中添加了一組散列容器和與之相關的算法。


                //定義
                pair<intstring> ming(1,"ming1");
                map
            <int ,string> authors;
                
            //插入
                authors.insert(ming);
                authors.insert(map
            <intstring>::value_type(2,"ming2"));
                authors.insert(make_pair(
            3,"ming3"));
                
            //修改
                cout << "before changed " << authors[3<< endl;
                authors[
            3= "ming4";
                cout 
            <<" after changed "  << authors[3<< endl;
                
            //刪除
                cout <<" before erase "  << authors[2<< endl;
                map
            <intstring>::iterator iter = authors.find(2);
                
            if(iter != authors.end())
                {
                    authors.erase(iter);
                }    
                cout 
            <<" after changed "  << authors[2<< endl;

            輸出:

            before changed ming3
             after changed ming4
             before erase ming2
             after changed

                //刪除指針
                map<string, test4*> pointerMap;
                pointerMap.insert(make_pair(
            "1"new test4()));
                std::map
            <string, test4*>::iterator iter1;
                 
            for (iter1 = pointerMap.begin(); iter1 != pointerMap.end();++iter1)
                 {
                     delete  iter1
            ->second;
                 }


            亚洲国产欧洲综合997久久| 国内精品久久久久久久涩爱 | 久久久久综合中文字幕| 久久这里只有精品首页| 国产午夜福利精品久久2021| 香蕉久久一区二区不卡无毒影院| 久久99精品久久久久久水蜜桃| 精品国产乱码久久久久久呢| 久久青青草原精品影院| 亚洲中文字幕久久精品无码喷水| 久久国产精品99久久久久久老狼| 亚洲国产日韩欧美久久| 亚洲国产成人久久综合碰碰动漫3d | 久久高清一级毛片| 亚洲综合熟女久久久30p| 国产亚洲精久久久久久无码AV| 久久亚洲AV无码精品色午夜麻豆| 国内精品久久久久久野外| 狠狠色丁香久久婷婷综合蜜芽五月 | 久久精品国产黑森林| 狠狠88综合久久久久综合网| 伊人久久大香线蕉综合5g| 99久久国产免费福利| 久久精品国产亚洲AV无码偷窥| 日本高清无卡码一区二区久久| 99久久国产主播综合精品| 色婷婷综合久久久久中文一区二区| 久久久久人妻一区精品| 精品久久久无码中文字幕天天 | 囯产精品久久久久久久久蜜桃 | 国产91久久综合| 久久91综合国产91久久精品| 色偷偷久久一区二区三区| 亚洲精品高清一二区久久| 久久久久无码专区亚洲av| 国内精品免费久久影院| 国产叼嘿久久精品久久| 久久久亚洲精品蜜桃臀| 日本久久中文字幕| 亚洲色欲久久久久综合网| 久久精品国产亚洲av麻豆图片|