• <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>

            VC++中CMAP的使用

            映射表類(CMap)是MFC集合類中的一個模板類,也稱作為“字典”,就像一種只有兩列的表格,一列是關(guān)鍵字,一列是數(shù)據(jù)項,它們是一一對應(yīng)的。關(guān)鍵字是唯一的,給出一個關(guān)鍵字,映射表類會很快找到對應(yīng)的數(shù)據(jù)項。映射表的查找是以哈希表的方式進(jìn)行的,因此在映射表中查找數(shù)值項的速度很快。映射類最適用于需要根據(jù)關(guān)鍵字進(jìn)行快速檢索的場合,我們的程序中就用映射表來保存計時器標(biāo)志值和類實例指針,用計時器的標(biāo)志值作為關(guān)鍵字。 他這個有點像數(shù)組,比如你要查找a[index],不必先遍歷前面的index個元素,只不過數(shù)組的下標(biāo)是哈希表鍵值,它是以鍵值對的形式出現(xiàn)的。舉個例子來說吧,公司的所有職員都有一個工號和自己的姓名,工號就是姓名的關(guān)鍵字,給出一個工號,就可以很快的找到相應(yīng)的姓名。
                    舉例如下:
            1、定義一個CMAP,向這個CMAP中增加數(shù)據(jù)項(鍵-值對)。
            CMap<CString, LPCTSTR, CString, LPCTSTR>m_ItemMap;
            CString strKey = _T(""), str = _T("");
            int i;
            for(i = 0; i < 5; i++)
                {
                    strKey.Format("%d", i);             
            //這個是鍵
                    str.Format("A%d", i);              
            //鍵對應(yīng)的
                    m_ItemMap.SetAt(strKey, str);
                }
            2、遍歷正個CMAP的常用方法。
                POSITION pos = m_ItemMap.GetStartPosition();
                while(pos)
                {
                    m_ItemMap.GetNextAssoc(pos, strKey, str);
                    cout<< strKey<< ":"<< str<< endl;
                }
            3、在CMAP中查找相應(yīng)的數(shù)據(jù)項。
                CString pReset;
                if(m_ItemMap.Lookup("1", pReset))
                {
                    cout<<pReset<<endl;
                }


            =======================================================================現(xiàn)在,我們來學(xué)習(xí)MFC中,最常用的數(shù)據(jù)結(jié)構(gòu)中的最后一個CMap模板。之前,我們已經(jīng)依次學(xué)完了CArray,CList,并且也對它們進(jìn)行了初步的剖析。

            其實,我一直認(rèn)為CMap是最簡單的一個數(shù)據(jù)類型,如果說,大家對這個數(shù)據(jù)類型產(chǎn)生不良感覺的話,大多是因為對Hash表的陌生。

            顯然,CMap就是對Hash表的一種實現(xiàn)。對于Hash表來說,我們需要提供成對的Key與Value進(jìn)行操作,其實,也就是將我們?nèi)粘J褂玫臄?shù)組下標(biāo)替換成現(xiàn)在Key,至于MFC是采用了什么樣的散列函數(shù),我們不必知道。

            Hash表可以認(rèn)為是數(shù)組的一種優(yōu)化,或者說是對數(shù)組缺陷的一種彌補(bǔ),因為我們知道,數(shù)組在具備了高效存取性能的同時,無法動態(tài)的調(diào)整自身的大小,又嚴(yán)重的影響了它的使用效果。這給了Hash表可乘之機(jī),Hash表總是使用了某種算法盡可能的來達(dá)到將成對的元素存儲到一個額定的離散的內(nèi)存空間,它既繼承了鏈表對自身的動態(tài)調(diào)整,又盡可能的使讀寫維持在高速的水平,當(dāng)然無論如何還是要比數(shù)組慢的多。

            如果你非要讓我告訴你,Hash表是什么樣的一個數(shù)據(jù)結(jié)構(gòu)的話,很遺憾,我無法準(zhǔn)確的描述,這就相當(dāng)于你問我“鳳凰是什么樣子”,不過我可以告訴你孔雀的樣子。常用的Hash表非常像一個十字?jǐn)?shù)組,似乎十字?jǐn)?shù)組又成為了眾多讀者的障礙,如果你暫時還不能理解的話,請你去翻閱Hash表的詳細(xì)論述,當(dāng)然你也可以在不久之后,在本處看到這些經(jīng)典數(shù)據(jù)結(jié)構(gòu)的精講。

            現(xiàn)在,我們來看一個CMap的用法,至于它的參數(shù),你可以看本空間一篇專門描述CArray,CList以及CMap參數(shù)用法的文章《CArray,CList,CMap如何實化(實例化)》。下面是我自己編寫的例子:

            class Point

            {

            public:

                Point()

                {

                    m_x = 0;

                    m_y = 0;

                }

                Point(int x, int y)

                {

                    m_x = x;

                    m_y = y;

                }

            public:

                int m_x;

                int m_y;

            };

            typedef CMap<const char*, const char*, Point, Point&>     CMapPnt; //請在使用之前定義

            int main()

            {

                Point elem1(1, 100), elem2(2, 200), elem3(3, 300), point;

                CMapPnt mp;

                // insert 3 elements into map          #1

                mp.SetAt("1st", elem1);

                mp.SetAt("2nd", elem2);

                mp.SetAt("3th", elem3);

               

                // search a point named "2nd" from map                  #2

                mp.Lookup("2nd", point);

                printf("2nd: m_x: %d, m_y: %d\n", point.m_x, point.m_y);

            // insert a new pair into map      #3

            Point elem4(4, 400);

            mp["4th"] = elem4;

            cout<<"count: "<<mp.GetCount()<<endl;

            // traverse the entire map                    #4

            size_t index = 0;

            const char* pszKey;

            POSITION ps = mp.GetStartPosition();

            while( ps )

            {  

            mp.GetNextAssoc(ps, pszKey, point);

            printf("index: %d, m_x: %d, m_y: %d\n", ++index, point.m_x, point.m_y);

            }

            return 0;

            }

            代碼中,我已經(jīng)給出了一些注釋,我同樣建議讀者們,用英文在代碼中注釋,這樣的好處實在是太多了。尤其在代碼需要在不同編碼的操作系統(tǒng)上調(diào)試的時候。

            對于CMap這個類,我不得不著重啰嗦一下的是:遍歷操作以及取下標(biāo)【】操作,當(dāng)然還有那個令很多人困惑不已的ARG_KEY到底應(yīng)該如何選擇的問題。

            遍歷,看注釋#4,至于POSITION的含義,請在本空間,查看其它文章。先使用GetStartPosition()函數(shù)獲得表頭的位置,然后,我們可以使用GetNextAssoc函數(shù)來遍歷。GetNextAssoc(POSITION& rNextPosition, KEY& rKey, VALUE& rValue)函數(shù)的參數(shù)值得說明一下,大家看到,3個參數(shù)都是引用,而第一個是rNextPosition,顧名思義,在函數(shù)返回之后,它將會指像下一個元組,當(dāng)然這是在表還未遍歷完的時候,否則,它將被置為空(NULL)。

            【】,利用下標(biāo)取元素的這個操作符,在CMap中被重載,用來返回指定Key值數(shù)據(jù)的引用,不過在注釋#3處,對于先取"4th"這個Point的引用然后賦值的用法,看起來,似乎有點聰明過了頭,因為在這之前,我們還沒有插入"4th"所對應(yīng)的元組,但是,程序卻能正常的運(yùn)行!為什么?其實,這樣的用法是十分正確的,因為CMap畢竟不是數(shù)組,它是沒有邊界的,當(dāng)CMap在獲得一個它無法查詢到的Key值的時候,它會將這個Key以及一個空的數(shù)據(jù)類型追加到Hash表中去,從而保證了上面的程序可以無誤的運(yùn)行。

            我們已經(jīng)說過,ARG_KEY是作為類型參數(shù)傳入CMap的,但并不是任何類型都可以作為ARG_KEY傳入的。為什么?看樣子,這次不得不簡單的說說Hash表的散列函數(shù)了。每個Hash表,總會使用一些散列函數(shù),用來查找Key所對應(yīng)的Value,理想狀態(tài)下,我們當(dāng)然希望Hash表,就是一個數(shù)組,雖然這不可能,不過這樣理解,可以幫助我們更好的理解Hash表的物理結(jié)構(gòu),就讓我們暫時把它看成一個數(shù)組吧。數(shù)組總是使用下標(biāo)來直接獲取元素的存儲地址,而下標(biāo),顯然應(yīng)該是個非負(fù)整數(shù),從而Hash表,也應(yīng)該具備這樣的特性,至少必須存在某種算法可以使傳入的Key可以直接的轉(zhuǎn)化為一個非負(fù)的整數(shù),這也就是ARG_KEY的選擇標(biāo)準(zhǔn)。從而對象、引用無論如何都不應(yīng)該作為ARG_KEY成為CMap的類型參數(shù),而int、unsigned int、指針以及地址就成為了ARG_KEY的常用類型參數(shù),其實也就是那些類似于整型的數(shù)據(jù)類型。常常看到一些人在用CMap的時候,試圖使用CString作為CMap中ARG_KEY的類型參數(shù),這是應(yīng)該被糾正的方向性錯誤,但有些人似乎會理直氣壯的反駁我,因為他們發(fā)現(xiàn)類型參數(shù)KEY是可以使用CString的,這很奇怪嗎?我說過KEY不能使用CString嗎?之所以KEY可以使用CString而ARG_KEY卻用的是LPCTSTR,那是因為CString重載了operator==(const char*)這個判等操作符,當(dāng)CMap從Hash表中獲得KEY之后,它會將ARG_KEY與KEY直接相比較。真正存于CMap內(nèi)部的是KEY,也就是CString。這也就是為什么,我們經(jīng)常會看到CMap被實化成CMap<CString, LPCTSTR/*相當(dāng)于const char*,非Unicode情況下*/, CString,CString&>這樣的一個四不像實化類的原因,至于CMap的效率優(yōu)化問題,我們會在以后的文章中繼續(xù)與大家探討。

            CMap的確是個很不錯的數(shù)據(jù)結(jié)構(gòu),尤其在你建立一個字典的時候。比如idealsoft的含義是"曳光科技",這就是一個元組,也就是一個Pair,Key是"idealsoft",而Value是"曳光科技"。

            ====================================================================
            #include   <afxwin.h>
            #include   <afxtempl.h>
            void   main()
            {
            AfxWinInit(::GetModuleHandle(NULL),   NULL,   ::GetCommandLine(),   0);
            CMap <int,   int,   CString,   CString>   m_cMap;
            m_cMap.SetAt(9923033,     "張三 ");
            m_cMap.SetAt(9826033,     "張A ");
            m_cMap.SetAt(9923063,     "張B ");
            m_cMap.SetAt(9923093,     "張C ");
            CString   strName;
            m_cMap.Lookup(9923063,   strName);
            AfxMessageBox(strName);
            }


            posted on 2011-10-21 09:38 wrh 閱讀(19212) 評論(0)  編輯 收藏 引用


            只有注冊用戶登錄后才能發(fā)表評論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            導(dǎo)航

            <2011年10月>
            2526272829301
            2345678
            9101112131415
            16171819202122
            23242526272829
            303112345

            統(tǒng)計

            常用鏈接

            留言簿(19)

            隨筆檔案

            文章檔案

            收藏夾

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            久久无码人妻一区二区三区午夜| 香港aa三级久久三级老师2021国产三级精品三级在 | 日产精品久久久久久久性色| 国产亚洲综合久久系列| 国产毛片久久久久久国产毛片| 久久人妻少妇嫩草AV蜜桃| 中文字幕热久久久久久久| 久久久久成人精品无码中文字幕| 国产精品成人久久久久久久| 亚洲精品无码久久久久| 国产精品美女久久久网AV| 国产精品久久久久久久人人看| 久久精品www人人爽人人| 久久国产精品波多野结衣AV| 日产精品久久久久久久性色| 中文字幕无码av激情不卡久久| 国产精品久久久久久一区二区三区| 色综合久久天天综线观看| 精品久久久久久亚洲| 久久综合给合久久狠狠狠97色 | 久久精品国产72国产精福利| 99久久精品午夜一区二区| 久久久久无码精品| 99久久精品久久久久久清纯| 国产精品9999久久久久| 香蕉久久av一区二区三区| 亚洲欧美成人久久综合中文网| 国产精品成人无码久久久久久 | 精品久久久久成人码免费动漫| 国产成人精品久久亚洲高清不卡 | 久久狠狠高潮亚洲精品| 伊人久久大香线蕉亚洲| 2019久久久高清456| 精品久久久一二三区| 亚洲中文久久精品无码| 久久综合亚洲色HEZYO社区| 性做久久久久久免费观看| 亚洲精品高清一二区久久| 亚洲国产精品成人AV无码久久综合影院 | 久久久久国产精品麻豆AR影院 | 久久人人爽人人爽AV片|