程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> map拔出自界說對象總結

map拔出自界說對象總結

編輯:關於C++

map拔出自界說對象總結。本站提示廣大學習愛好者:(map拔出自界說對象總結)文章只能為提供參考,不一定能成為您想要的結果。以下是map拔出自界說對象總結正文


豈非拔出map還有甚麼講求嗎?我們且看map在STL中的界說辦法:
template <class Key, class T, class Compare = less<Key>, class Alloc = alloc>
第一個參數Key是症結字類型
第二個參數T是值類型
第三個參數Compare是比擬函數(仿函數)
第四個參數是內存設置裝備擺設對象

map外部存儲機制現實是以紅黑樹為基本,紅黑樹在拔出節點時,必需按照年夜小比對以後在一個適合的地位上履行拔出舉措。所以作為症結字,最少必需有“<”這個比擬操作符。我們曉得,int,float,enum,size_t等等簡略症結字,都有內置的比擬函數,與map搭配不管是拔出照樣查找,都沒甚麼成績。然則作為龐雜數據類型,假如沒有明白界說“<”比擬操作符,就不克不及與map直接搭配應用,除非我們本身界說第三個參數。

在選擇map的症結字時,留意以下兩點,同時這兩點也是改錯的辦法:
a) 症結字明白界說“<”比擬操作符
b) 沒有“<”比擬操作符,自界說仿函數替換第三個參數Compare,該仿函數完成“()”操作符,供給比擬功效。拔出時各節點次序以該仿函數為綱。

以std::pair為症結字摻入map
上面我們先寫一個有毛病的函數,在剖析毛病緣由以後,慢慢停止修改。

#include <map>

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

這個法式必定掉敗,假如非要如斯應用,上述a辦法明顯不合適,std::pair是已界說好的構造體弗成修正。只能應用b辦法了,界說一個比擬類改革以下:

#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

#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;
}

編譯這個法式也是毛病的,毛病意思年夜概也是沒有界說“<”比擬函數。由於struct st是我們本身界說的構造體,所以修正這個法式可使用下面a、b兩種辦法。我們先談第一種,第一次修正時我也弄錯了,我是如許界說比擬函數的。

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

為何會湧現這個成績呢?我們深刻STL的源代碼看下。既然說是/usr/include/c++/3.2.3/bits/stl_function.h的197行出了成績,且看這行是甚麼。

   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));}

以友聯函數取代函數外部界說的比擬操作符,STL外部也多是以這類方法界說的。假如我非要之內部界說的方法呢?可使用b辦法,我們自界說一個比擬仿函數,替換默許的less。

拔出函數前往值
在map容器中拔出數據有許多函數可用,這裡只評論辯論最通俗的insert操作,在STL中它是如許界說的。
pair<iterator, bool> insert(const value_type& x);
map容器不許可鍵值反復,在履行拔出操作後,可以憑仗該前往值獲得操作成果。前往值是一個迭代器和布爾值的鍵值對,迭代器指向map中具有該值的元素,布爾值表現能否拔出勝利。假如布爾值為true,表現拔出勝利,則迭代器為新拔出值在map中的地位;布爾值為false,表現拔出掉敗(曾經存在該值),迭代器為原有值在map中的地位。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved