Effective STL 學習筆記: Item 22 ~ 24

1 避免 \(set \& multiset\) 在原位改變 Key

set, multiset, map, multimap 都是有序的容器,若是直接在原位改變 key 的值,則頗有可能容器不有序,後續對該容器的算法會失效。 css

2 Consider replacing associative containers with sorted vectors

Associative Container 中的每一個 Node 除了保存真正對象外,還須要維護指向 Parent, Previous, Next 的三個指針,相比 vector 來講,更佔用內存,範文時間爲 O(logn)。 而 vectors,若是配合合適的 Hash Function ,則既省時間又省空間,但不足之處是須要本身始終維持 vector 在有序的狀態。 java

3 Choose carefully between map::operator[] and map-insert

map::operator[] 會返回 Value 的一個引用,而若是對應的 Key 在 Map 中沒有 Value, map 會調用 Default Constructor 來建立一個新的,加到 Map 中,而後再將新的 Value 返回出來,例如,下面的代碼中: c++

 1: class Widget
 2: {
 3: public:
 4:     Widget(){}
 5:     Widget(double d):m_value(d){}
 6:     virtual ~Widget(){}
 7: private:
 8:     double m_value;
 9: };
10: 
11: map<int, Widget> m;
12: m[1] = 1.50;

第 12 行一行代碼實際上和下面的代碼是等效的: 算法

13: pair<map<int, Widget>::iterator, bool> result =
14:         m.insert(map<int, Widget>::value_type(1, Widget()));
15: result.first->second = 1.50;

實際上,咱們能夠用下面的一行代碼來完成所需操做,避免無謂的默認構造: sql

m.insert(map<int, Widget>::value_type(1, 1.50));

但若是咱們想更新已有的 Key, 則 [ ] 更簡單一些。 bash

書中最後給出了一個例子,用於高效的添加或者更新 map: ide

 1: template <typename MapType,
 2:           typename KeyType,
 3:           typename ValueType>
 4: typename MapType::iterator
 5: efficientAddOrUpdate(MapType&         map,
 6:                      cons KeyType&    k,
 7:                      const ValueType& v)
 8: {
 9:     typename MapType::iterator lb = m.lower_bound(k);
10:     if (lb != m.end() && !(m.key_comp()(k, lb->first)))
11:     {
12:         lb->second = v;
13:         return lb;
14:     }
15:     else
16:     {
17:         typedef typename MapType::value_type MVT;
18:         return m.insert(lb, MVT(k,v));
19:     }
20: }
相關文章
相關標籤/搜索