日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Map以自定义类做为键值

發(fā)布時間:2023/12/2 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Map以自定义类做为键值 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

map在STL中的定義

?

template <class Key, class T, class Compare = less<Key>, class Alloc = alloc>

?第一個參數(shù)Key是關鍵字類型

第二個參數(shù)T是值類型

第三個參數(shù)Compare是比較函數(shù)(仿函數(shù))

第四個參數(shù)是內(nèi)存配置對象

?

map內(nèi)部存儲機制實際是以紅黑樹為基礎,紅黑樹在插入節(jié)點時,必須依照大小比對之后在一個合適的位置上執(zhí)行插入動作。所以作為關鍵字,起碼必須有“<”這個比較操作符。我們知道,int,float,enum,size_t等等簡單關鍵字,都有內(nèi)置的比較函數(shù),與map搭配無論是插入還是查找,都沒什么問題。但是作為復雜數(shù)據(jù)類型,如果沒有明確定義“<”比較操作符,就不能與map直接搭配使用,除非我們自己定義第三個參數(shù)。

在選擇map的關鍵字時,注意以下兩點,同時這兩點也是改錯的方法:

a) 關鍵字明確定義“<”比較操作符

b) 沒有“<”比較操作符,自定義仿函數(shù)替代第三個參數(shù)Compare,該仿函數(shù)實現(xiàn)“()”操作符,提供比較功能。插入時各節(jié)點順序以該仿函數(shù)為綱。

?

以std::pair為關鍵字摻入map
下面我們先寫一個有錯誤的函數(shù),在分析錯誤原因之后,逐步進行修正。

#include <map>
int main()
{
?????? std::map<std::pair<int, int>, int> res;
?????? res.insert(std::make_pair(12,33), 33);
}

?這個程序一定失敗,如果非要如此使用,上述a方法顯然不適合,std::pair是已定義好的結構體不可修改。只能使用b方法了,定義一個比較類改造如下:

[cpp]?view plaincopy print?
  • #include?<map>??
  • ??
  • struct?comp??
  • ??
  • {??
  • ??
  • ???????typedef?std::pair<int,?int>?value_type;??
  • ??
  • ???????bool?operator?()?(const?value_type?&?ls,?const?value_type?&rs)??
  • ??
  • ???????{??
  • ??
  • ??????????????return?ls.first?<?rs.first?||?(ls.first?==?rs.first?&&?ls.second?<?rs.second);??
  • ??
  • ???????}??
  • ??
  • };??
  • ??
  • int?main()??
  • ??
  • {??
  • ??
  • ???????std::map<std::pair<int,?int>,?int,?comp>?res;??
  • ??
  • ???????res.insert(std::make_pair(std::make_pair(12,33),?33));??
  • ??
  • ???????res.insert(std::make_pair(std::make_pair(121,331),?331));??
  • ??
  • ???????res.insert(std::make_pair(std::make_pair(122,332),?332));??
  • ??
  • ????????
  • ??
  • ???????std::map<std::pair<int,?int>,?int,?comp>::iterator?it?=?res.find(std::make_pair(121,331));??
  • ??
  • ???????if?(it?==?res.end())??
  • ??
  • ??????????????printf("NULL"n");??
  • ??
  • ???????else??
  • ??
  • ??????????????printf("%d?%d?%d?"n",?it->first.first,?it->first.second,?it->second);??
  • ??
  • ????return?0;??
  • ??
  • }??
  • 以結構體或類為關鍵字插入map

    ?

    [cpp]?view plaincopy print?
  • #include?<map>??
  • ??
  • struct?st??
  • ??
  • {??
  • ??
  • ???????int?a,?b;??
  • ??
  • ???????st():a(0),?b(0){}??
  • ??
  • ???????st(int?x,?int?y):a(x),?b(y){}??
  • ??
  • };??
  • ??
  • int?main()??
  • ??
  • {??
  • ??
  • ???????std::map<struct?st,?int>?res;??
  • ??
  • ???????res.insert(std::make_pair(st(1,2),?12));??
  • ??
  • ???????res.insert(std::make_pair(st(30,4),?34));??
  • ??
  • ???????res.insert(std::make_pair(st(5,6),?56));??
  • ??
  • ????????
  • ??
  • ???????std::map<struct?st,?int>::iterator?it?=?res.find(st(30,4));??
  • ??
  • ???????if?(it?==?res.end())??
  • ??
  • ??????????????printf("NULL"n");??
  • ??
  • ???????else??
  • ??
  • ??????????????printf("first:%d?second:%d?%d"n",?it->first.a,?it->first.b,?it->second);??
  • ??
  • ???????return?0;??
  • ??
  • }??
  • 編譯這個程序也是錯誤的,錯誤意思大概也是沒有定義“<”比較函數(shù)。因為struct st是我們自己定義的結構體,所以修改這個程序可以使用上面ab兩種方法。我們先談第一種,第一次修改時我也搞錯了,我是這樣定義比較函數(shù)的。 [cpp]?view plaincopy print?
  • struct?st??
  • ??
  • {??
  • ??
  • ???????int?a,?b;??
  • ??
  • ???????st():a(0),?b(0){}??
  • ??
  • ???????st(int?x,?int?y):a(x),?b(y){}??
  • ??
  • bool?operator?<?(const?struct?st?&rs)?{return?(this->a?<?rs.a?||?(this->a?==?rs.a?&&?this->b?<?rs.b));}??
  • ??
  • };??
  • 按照這個改動再次編譯程序還是錯誤,有個如下這樣的提示:

    /usr/include/c++/3.2.3/bits/stl_function.h:197: passing `const st' as `this' argument of `bool st::operator<(const st&)' discards qualifiers

    ???????為什么會出現(xiàn)這個?問題呢?我們深入STL的源代碼看下。既然說是/usr/include/c++/3.2.3/bits/stl_function.h197行出了問題,且看這行是什么。

    ?? 193?/// One of the @link s20_3_3_comparisons comparison functors@endlink.

    ?? 194?template <class _Tp>

    ?? 195?struct less : public binary_function<_Tp,_Tp,bool>

    ?? 196?{

    ?? 197??? ???bool operator()(const _Tp& __x, const _Tp& __y) const { return __x < __y; }

    ?? 198?};

    ?

    struct st中的“<”在編譯后真正是什么樣子呢?大概是bool operator < (struct st &ls, const struct st &rs)。在less調用這個比較符時,它都是以const方式傳入,不可能再以非const方式調用,故出錯。修正如下

    struct st

    {

    ?????? int a, b;

    ?????? st():a(0), b(0){}

    ?????? st(int x, int y):a(x), b(y){}

    ?????? friend bool operator < (const struct st &ls, const struct st &rs);

    };

    inline bool operator < (const struct st &ls, const struct st &rs)

    {return (ls.a < rs.a || (ls.a == rs.a && ls.b < rs.b));}

    ?以友聯(lián)函數(shù)代替函數(shù)內(nèi)部定義的比較操作符,STL內(nèi)部也多是以這種方式定義的。如果我非要以內(nèi)部定義的方式呢?可以使用b方法,我們自定義一個比較仿函數(shù),替代默認的less

    插入函數(shù)返回值

    ???????map容器中插入數(shù)據(jù)有很多函數(shù)可用,這里只討論最普通的insert操作,在STL中它是這樣定義的。

    ?????? pair<iterator, bool> insert(const value_type& x);

    ?????? map容器不允許鍵值重復,在執(zhí)行插入操作后,可以憑借該返回值獲取操作結果。返回值是一個迭代器和布爾值的鍵值對,迭代器指向map中具有該值的元素,布爾值表示是否插入成功。如果布爾值為true,表示插入成功,則迭代器為新插入值在map中的位置;布爾值為false,表示插入失敗(已經(jīng)存在該值),迭代器為原有值在map中的位置。

    ?

    ?

    [cpp]?view plaincopy print?
  • #include?<map>??
  • #include?<iostream>??
  • using?namespace?std;??
  • ??
  • class?Key??
  • {??
  • public:??
  • ????Key();??
  • ????Key(int?v);??
  • ????int?_key;??
  • ????~Key();??
  • ????/*重載<作為成員函數(shù)不行,兩個操作數(shù)都要求是const*/??
  • ????//bool?operator?<(const?Key&?key);??
  • };??
  • bool?operator?<(const?Key?&key1,const?Key?&key2)??
  • {??
  • ????if(key1._key<key2._key)??
  • ????????return?true;??
  • ????else??
  • ????????return?false;??
  • }??
  • Key::Key()??
  • {??
  • }??
  • Key::Key(int?v)??
  • {??
  • ????_key=v;??
  • }??
  • Key::~Key()??
  • {??
  • }??
  • ??
  • void?main()??
  • {??
  • ??????
  • ????map<Key,int>?ClassMap;??
  • ????Key?one(1);??
  • ????ClassMap.insert(make_pair(one,1));??
  • ????Key?two(2);??
  • ????ClassMap.insert(make_pair(two,2));??
  • ????Key?three(3);??
  • ????ClassMap.insert(make_pair(three,3));??
  • ????map<Key,int>::iterator?itor=ClassMap.begin();??
  • ????while(itor!=ClassMap.end())??
  • ????{??
  • ????????cout<<itor->first._key<<"?~~?"<<itor->second<<endl;??
  • ????????++itor;??
  • ????}??
  • }??
  • 創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎

    總結

    以上是生活随笔為你收集整理的Map以自定义类做为键值的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。