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

            兔子的技術博客

            兔子

               :: 首頁 :: 聯系 :: 聚合  :: 管理
              202 Posts :: 0 Stories :: 43 Comments :: 0 Trackbacks

            留言簿(10)

            最新評論

            閱讀排行榜

            評論排行榜

            Hash

            我曾在很多C++書籍中看到作者們抱怨標準庫中沒有實現hash_sethase_map,并非常自信地聲稱在下一個標準庫中一定會增加這兩個。我搜索的幫助文檔后,很遺憾地沒有發現相關庫。難道C++的狂熱愛好者把這么重要的庫給忘記了嗎?Boost.Functional/hash庫引進了我的注意,遵循它的指引,我一步一步發發現的散列表的蹤跡。

            hash        <boost/functional/hash.hpp>

            觀察頭文件的寫法,就知道hashfunctional庫中的一員,更進一步,如果你用過STL中的<functional>,那么多半你也猜到,hash是一個函數。不太完全正確,實事上它是一個函數對象。boost中實現的散列表,使用的散列函數就是它(至于boost中有那些散列函數,以后再列舉)。

            如果直接使用hash,先創建一個實例并像函數一樣調用它:

                   hash<string> string_hash;

                   size_t h = string_hash(“Love”);

            它支持的類型有

            integers

            floats

            pointers

            strings

            擴展類型有

            arrays

            std::pair

            標準容器

            定制的類型擴展

            如何定制類型

            要編寫一個hash可用的類型,兩個必須實現的功能是operator==  hash_value,參考下面的實現:

            namespace library {

                   struct book {

                          int id;

                          std::string titile;

                   };

                   std::size_t hash_value(const book& b) {

                          boost::hash<int> hasher;

                          return hasher(b.id); // 可以自己寫哈希函數

                   }

                   bool operator== (const book& a, const book& b) const {

                          return a.id == b.id;

                   }

            }; // namespace library

            結合散列值

            縱觀上面的hash使用方法,只能對一個參數可hash值。庫也提供了多個參數,示例:

            class point {

                   int x, y;

            public:

                   … …

                   bool operator==(const point& other) const {      

                          return x == other.x && y == other.y;

                   }

                   friend std::size_t hash_value(const point& p) {

                          std::size_t seed = 0;

                          boost::hash_combin(seed, p.x);     // combin 的順序不同,得出的結果也不同

                          boost::hash_combin(seed, p.y);

                          return seed;

            };

            Unordered      <boost/unordered_set.hpp> ,<boost/unordered_map.hpp>

            這個庫實現了無序關聯容器。從某種意義上說,它就是我們需要的散列表。

            與有序關聯容器不同的是,它不需要比較,而是需要hash值。我下面列出它的聲明,以求不要理解錯了。

            namespace boost {

                   template <

                          class Key,

                          class Hash = boost::hash<Key>,

                          class Pred = std::equal_to<Key>,

                          class Alloc = std::alloctor<Key> >

                   class unordered_set;

            }

            如果class不是標準庫里的類型,那么hashequal_to的非常關鍵了。

            使用

            unordered_setunordered_mapsetmap在使用上基本一致。請參考它們的寫法。

            更深層次的探索

            散列表一個不可避免的問題即是“沖突”,解決沖突的方法有很多,有分離鏈表法、線性探測等。據我所知道,分離鏈表法是在各種庫最常用的方法。unordered的實現用到了桶(bucket),這屬于分離鏈表的變體。每桶對應的是索引,桶里可以有很多元素,它們都是“沖突”的。

            線性探測中,一個非常重要的數據就是:裝填因子λ,它是散列表中的元素個數與散列表大小的比值。對于探測散列表,λ≈0.5;對于分離鏈表,λ≈1。在手冊中,unordered中負載因子(load factor)的解釋是“the average number of elements per bucket”,平均每個桶中元素的個數,在數學上,此處的負載因子與前面的裝填因子λ等價。

            以下幾個函數用于控制桶的大小

            X( size_type n)                                  構造一個新容器,帶有n個桶

            X( InputIterator i, InputIterator j, size_type n)            構造有n個的容器,插入區間[i, j)

            float load_factor( ) const                            每個桶中的平均數量

            float max_load_factor( ) const             當前最大的負載因子

            float max_load_factor( float z)             修改最大負載因子,z做為參數

            void rehash( size_type n)                     修改桶使至少為n個,且負載因子小于最大負載因子

            除了 rehash 以外,其它成員函數如何影響桶的數量并沒有規定,insert 操作僅當插入導致負載因子大于或等于最大負載因子時允許使得迭代器失效。對于多數實現來說,這意味著只有當此事發生時,插入操作才會改變桶的數量。因此,迭代器只會在調用 insert  rehash 時才可能失效,而指向容器中的元素的指針和引用則永不失效。


            轉自:http://hi.baidu.com/ani_di/blog/item/41406ce6df3c1f24b83820c1.html

            posted on 2010-06-05 17:23 會飛的兔子 閱讀(7868) 評論(0)  編輯 收藏 引用 所屬分類: C++庫,組件
            国产一区二区三精品久久久无广告| 久久久久高潮综合影院| 色综合久久综合中文综合网| 色婷婷综合久久久中文字幕| 精品久久久久久综合日本| 久久午夜综合久久| 伊人久久精品无码av一区| 久久免费小视频| 久久妇女高潮几次MBA| 久久久久亚洲AV无码专区首JN| 国内精品久久久久国产盗摄| 国产精品成人精品久久久| 青青草原综合久久大伊人导航| 久久99精品久久久久久齐齐| 久久久久久伊人高潮影院| 国产精品久久久亚洲| 色青青草原桃花久久综合| 久久精品一区二区| 久久综合香蕉国产蜜臀AV| 国产99久久久国产精免费| 久久亚洲精品无码AV红樱桃| 久久露脸国产精品| 热久久这里只有精品| 久久久久亚洲av无码专区| 亚洲国产精品狼友中文久久久| 国产亚洲精久久久久久无码| 婷婷久久综合| 久久久无码精品亚洲日韩软件| 国产69精品久久久久APP下载| 欧美一区二区三区久久综| 中文字幕精品久久| 国产 亚洲 欧美 另类 久久| …久久精品99久久香蕉国产| 伊人久久精品无码二区麻豆| 99久久综合国产精品免费| 久久综合九色欧美综合狠狠 | 漂亮人妻被中出中文字幕久久| 久久精品国产亚洲AV无码偷窥| 伊人久久大香线蕉AV一区二区| 国产精品久久久天天影视香蕉| 久久人人爽人人爽人人AV东京热 |