程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> STL---hash_map【十全十美】

STL---hash_map【十全十美】

編輯:關於C語言

    正在趕一個關於證劵交易的項目,其中用到了很多數據的查找等操作,開始用了map,同事看到後建議我用hash_map,查了查hash_map的內部實現,這裡順帶也就寫了下來。

    hash_map基於hash table哈希表)。 哈希表最大的優點,就是把數據的存儲和查找消耗的時間大大降低,幾乎可以看成是常數時間;而代價僅僅是消耗比較多的內存。然而在當前可利用內存越來越多的情況下,用空間換時間的做法是值得的。另外,編碼比較容易也是它的特點之一。     其基本原理是:使用一個下標范圍比較大的數組來存儲元素。可以設計一個函數哈希函數,也叫做散列函數),使得每個元素的關鍵字都與一個函數值即數組下標,hash值)相對應,於是用這個數組單元來存儲這個元素;也可以簡單的理解為,按照關鍵字為每一個元素“分類”,然後將這個元素存儲在相應“類”所對應的地方,稱為桶。但是,不能夠保證每個元素的關鍵字與函數值是一一對應的,因此極有可能出現對於不同的元素,卻計算出了相同的函數值,這樣就產生了“沖突”,換句話說,就是把不同的元素分在了相同的“類”之中。 總的來說,“直接定址”與“解決沖突”是哈希表的兩大特點。hash_map,首先分配一大片內存,形成許多桶。是利用hash函數,對key進行映射到不同區域桶)進行保 存。其插入過程是:    得到key    通過hash函數得到hash值    得到桶號(一般都為hash值對桶數求模)    存放key和value在桶內。 其取值過程是:    得到key    通過hash函數得到hash值    得到桶號(一般都為hash值對桶數求模)    比較桶的內部元素是否與key相等,若都不相等,則沒有找到。    取出相等的記錄的value。      hash_map中直接地址用hash函數生成,解決沖突,用比較函數解決。這裡可以看出,如果每個桶內部只有一個元素,那麼查找的時候只有一次比較。當許多桶內沒有值時,許多查詢就會更快了(指查不到的時候).    由此可見,要實現哈希表, 和用戶相關的是:hash函數和比較函數。這兩個參數剛好是我們在使用hash_map時需要指定的參數。     使用hash_map的一個簡單的例子:  
  1. #if defined(__GNUC__) 
  2. #if __GNUC__ < 3 && __GNUC__ >= 2 && __GNUC_MINOR__ >= 95 
  3. #include <hash_map> 
  4. #elif __GNUC__ >= 3 
  5. #include <ext/hash_map> 
  6. using namespace __gnu_cxx; 
  7. #else 
  8. #include <hash_map.h> 
  9. #endif 
  10. #elif defined(__MSVC_VER__) 
  11. #if __MSVC_VER__ >= 7 
  12. #include <hash_map> 
  13. #else 
  14. #error "std::hash_map is not available with this compiler" 
  15. #endif 
  16. #elif defined(__sgi__) 
  17. #include <hash_map> 
  18. #else 
  19. #error "std::hash_map is not available with this compiler" 
  20. #endif 
  21. #include <string> 
  22. #include <iostream> 
  23. #include <algorithm> 
  24. using namespace std; 
  25. struct str_hash{ 
  26.         size_t operator()(const string& str) const 
  27.         { 
  28.                 return __stl_hash_string(str.c_str()); 
  29.         } 
  30. }; 
  31. struct str_equal{ 
  32.     bool operator()(const string& s1,const string& s2) const    {      
  33.    return s1==s2; 
  34.     } 
  35. }; 
  36.  
  37. int main(int argc, char *argv[]) 
  38.         hash_map<string,string,str_hash,str_equal> mymap; 
  39.         mymap.insert(pair<string,string>("hcq","20")); 
  40.         mymap["sgx"]="24"; 
  41.         mymap["sb"]="23"; 
  42.         cout<<mymap["sb"]<<endl; 
  43.         if(mymap.find("hcq")!=mymap.end()) 
  44.         cout<<mymap["hcq"]<<endl; 
  45.         return 0; 
hash_map與map的區別:    1、構造函數。hash_map需要hash函數,等於函數;map只需要比較函數(小於函數).    2、存儲結構。hash_map采用hash表存儲,map一般采用紅黑樹(RB Tree)實現。因此其memory數據結構是不一樣的。      總體來說,hash_map 查找速度會比map快,而且查找速度基本和數據數據量大小,屬於常數級別;而map的查找速度是log(n)級別。並不一定常數就比log(n)小,hash還有hash函數的耗時,明白了吧,如果你考慮效率,特別是在元素達到一定數量級時,考慮考慮hash_map。但若你對內存使用特別嚴格,希望程序盡可能少消耗內存,那麼一定要小心,hash_map可能會讓你陷入尴尬,特別是當你的hash_map對象特別多時,你就更無法控制了,而且hash_map的構造速度較慢。現在知道如何選擇了嗎?權衡三個因素: 查找速度, 數據量, 內存使用。       哈哈,不說了,要不讓BOSS看到我不干活那就麻煩了……繼續工作!!!

 

本文出自 “驿落黃昏” 博客,轉載請與作者聯系!

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