青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

VC++中CMAP的使用

映射表類(CMap)是MFC集合類中的一個模板類,也稱作為“字典”,就像一種只有兩列的表格,一列是關鍵字,一列是數據項,它們是一一對應的。關鍵字是唯一的,給出一個關鍵字,映射表類會很快找到對應的數據項。映射表的查找是以哈希表的方式進行的,因此在映射表中查找數值項的速度很快。映射類最適用于需要根據關鍵字進行快速檢索的場合,我們的程序中就用映射表來保存計時器標志值和類實例指針,用計時器的標志值作為關鍵字。 他這個有點像數組,比如你要查找a[index],不必先遍歷前面的index個元素,只不過數組的下標是哈希表鍵值,它是以鍵值對的形式出現的。舉個例子來說吧,公司的所有職員都有一個工號和自己的姓名,工號就是姓名的關鍵字,給出一個工號,就可以很快的找到相應的姓名。
        舉例如下:
1、定義一個CMAP,向這個CMAP中增加數據項(鍵-值對)。
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);              
//鍵對應的
        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中查找相應的數據項。
    CString pReset;
    if(m_ItemMap.Lookup("1", pReset))
    {
        cout<<pReset<<endl;
    }


=======================================================================現在,我們來學習MFC中,最常用的數據結構中的最后一個CMap模板。之前,我們已經依次學完了CArray,CList,并且也對它們進行了初步的剖析。

其實,我一直認為CMap是最簡單的一個數據類型,如果說,大家對這個數據類型產生不良感覺的話,大多是因為對Hash表的陌生。

顯然,CMap就是對Hash表的一種實現。對于Hash表來說,我們需要提供成對的Key與Value進行操作,其實,也就是將我們日常使用的數組下標替換成現在Key,至于MFC是采用了什么樣的散列函數,我們不必知道。

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

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

現在,我們來看一個CMap的用法,至于它的參數,你可以看本空間一篇專門描述CArray,CList以及CMap參數用法的文章《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;

}

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

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

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

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

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

CMap的確是個很不錯的數據結構,尤其在你建立一個字典的時候。比如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 閱讀(19244) 評論(0)  編輯 收藏 引用


只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


導航

<2011年5月>
24252627282930
1234567
891011121314
15161718192021
22232425262728
2930311234

統計

常用鏈接

留言簿(19)

隨筆檔案

文章檔案

收藏夾

搜索

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            国产午夜精品在线| 欧美成人激情视频| 国产视频一区欧美| 国产精品久久毛片a| 欧美精品一区二区三区在线看午夜| 久久激情综合| 美女网站久久| 欧美精品一区二区三区蜜臀| 欧美日韩视频一区二区| 国产精品每日更新| 红桃视频国产一区| 99天天综合性| 久久成人精品| 亚洲国产合集| 欧美激情视频给我| 一本色道久久综合亚洲精品高清 | 欧美激情精品久久久久久久变态| 欧美精品尤物在线| 国产色婷婷国产综合在线理论片a| 一道本一区二区| 亚洲午夜激情在线| 亚洲一区二区三区四区中文| 欧美一区二区三区视频在线| 久久久精品久久久久| 欧美激情国产精品| 亚洲综合欧美日韩| 欧美jizzhd精品欧美巨大免费| 欧美日韩国产精品一区| 国产一区二区你懂的| 日韩视频一区二区| 久久久久九九视频| 日韩视频免费观看高清在线视频 | 好吊色欧美一区二区三区四区| 亚洲国产天堂久久综合| 午夜精品区一区二区三| 亚洲国产日韩美| 久久国产主播精品| 国产精品一区二区在线观看网站| 亚洲免费成人av| 欧美凹凸一区二区三区视频| 亚洲一区三区电影在线观看| 欧美激情国产精品| 在线观看国产日韩| 久久久久久91香蕉国产| 中国亚洲黄色| 欧美日韩在线播放一区二区| 亚洲肉体裸体xxxx137| 美女尤物久久精品| 欧美在线观看天堂一区二区三区| 欧美日韩亚洲高清一区二区| 亚洲三级影院| 欧美激情精品久久久久久蜜臀 | 久久一二三区| 国产亚洲精品久久久久婷婷瑜伽 | 欧美一区二视频| 亚洲精品欧美日韩专区| 美女脱光内衣内裤视频久久网站| 一区二区在线免费观看| 久久久久国产免费免费| 欧美一级夜夜爽| 国产日产欧美精品| 久久黄色网页| 欧美一区二区福利在线| 国产精品专区第二| 香蕉成人久久| 小黄鸭精品aⅴ导航网站入口| 国产精品久久久久一区二区三区共 | 亚洲网在线观看| 亚洲精品美女久久7777777| 久久婷婷国产综合国色天香| 韩日在线一区| 亚洲第一精品久久忘忧草社区| 亚洲欧美久久久| 国产在线一区二区三区四区| 久久久999| 久久夜色精品亚洲噜噜国产mv| 亚洲国产精品欧美一二99| 亚洲韩国精品一区| 欧美日韩亚洲一区三区| 亚洲专区一区| 欧美一二三区在线观看| 一区二区三区无毛| 亚洲第一精品福利| 国产精品成人va在线观看| 久久国产精彩视频| 久久综合一区二区| 亚洲午夜精品网| 欧美诱惑福利视频| 亚洲区国产区| 亚洲永久免费av| 亚洲国产毛片完整版| 日韩天堂在线观看| 国语自产精品视频在线看一大j8| 亚洲福利视频网| 国产精品午夜国产小视频| 欧美成人情趣视频| 国产精品亚洲成人| 欧美激情一区二区三级高清视频| 欧美色欧美亚洲另类二区| 久久视频精品在线| 欧美日韩国产区| 久久中文字幕一区| 欧美网站大全在线观看| 毛片一区二区三区| 国产精品久久久久久影院8一贰佰 国产精品久久久久久影视 | 亚洲高清激情| 国产麻豆午夜三级精品| 亚洲国产99精品国自产| 国产婷婷精品| 9人人澡人人爽人人精品| 一区二区在线免费观看| 亚洲在线电影| 亚洲无线观看| 欧美精品在线视频| 欧美国产日韩一区二区| 国产日韩欧美在线视频观看| 亚洲狼人综合| 亚洲精品欧美日韩| 久久爱www.| 久久精品国产亚洲5555| 国产精品久久综合| 夜夜嗨av一区二区三区免费区| 亚洲国产成人一区| 久久久精品免费视频| 久久精品国产96久久久香蕉| 欧美视频福利| 亚洲欧洲在线观看| 亚洲欧洲另类国产综合| 久久精品欧洲| 欧美色图五月天| 一本色道久久综合亚洲精品高清| 久久激情综合网| 欧美一区高清| 国产伦精品一区二区三区免费迷| 亚洲理论电影网| 亚洲精品一区二区三区樱花| 久久看片网站| 免播放器亚洲| 在线看片日韩| 久久永久免费| 蜜桃av综合| 亚洲第一福利社区| 免费成人性网站| 亚洲国产精品一区在线观看不卡| 在线日韩成人| 欧美国产精品日韩| 日韩午夜av电影| 午夜精品视频网站| 国产视频一区欧美| 久久精品二区亚洲w码| 老鸭窝毛片一区二区三区| 在线电影国产精品| 欧美成人精品在线视频| 亚洲黄色有码视频| 亚洲一区精品电影| 国产亚洲午夜| 久久香蕉国产线看观看av| 亚洲第一在线视频| 亚洲一区二区视频在线| 国产欧美一区二区三区视频| 久久99在线观看| 亚洲国产成人av| 亚洲神马久久| 韩日精品中文字幕| 欧美激情一区| 亚洲一区久久| 免费成人美女女| 9i看片成人免费高清| 国产麻豆一精品一av一免费| 久久精品成人欧美大片古装| 亚洲国产导航| 欧美一区二区三区免费看| 激情久久五月| 欧美色精品天天在线观看视频| 欧美亚洲专区| 亚洲美女av在线播放| 久久久噜噜噜久久人人看| 亚洲精品色婷婷福利天堂| 国产精品永久入口久久久| 免费在线国产精品| 午夜伦理片一区| 亚洲精品偷拍| 玖玖玖国产精品| 亚洲午夜日本在线观看| 国内一区二区在线视频观看 | 国产午夜精品美女视频明星a级 | 欧美一区二区三区在线| 亚洲人成啪啪网站| 国产日韩精品一区二区三区在线 | 国产性猛交xxxx免费看久久| 免费久久精品视频| 亚洲欧美日韩精品久久| 亚洲精品女人| 久久久一区二区| 美女成人午夜| 午夜久久久久久| 99在线观看免费视频精品观看| 国产一区二区高清视频| 欧美午夜无遮挡| 欧美激情视频给我|