版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、<p> 2008級(jí)軟件設(shè)計(jì)模式課程設(shè)計(jì)</p><p> (基于迭代器、適配器、策略模式的hashmap設(shè)計(jì))</p><p><b> 目的及簡(jiǎn)要介紹</b></p><p> 大家都知道,C++為廣大愛(ài)好者提供了諸如Iterator、list等容器供大家使用,大大的方便了大家處理數(shù)據(jù)。這里,我們同樣為大家提供一個(gè)滿足ST
2、L要求的容器來(lái)供大家使用,讓大家在數(shù)據(jù)處理的過(guò)程中能更方便快捷。</p><p> C++標(biāo)準(zhǔn)對(duì)容器提出了許多需求,只有滿足這些需求,才能算得上是STL容器。</p><p> 基本hashmap(散列表):STL中的最大的疏忽嗎?在STL中,沒(méi)有定義hashmap容器,這里我們實(shí)現(xiàn)了。</p><p> 散列表在平均情況下可以提供常量時(shí)間的插入、刪除和查找。
3、散列表并不是將元素有序地存儲(chǔ),而是把各元素散列(hash)或映射至某個(gè)桶(bucket)。只要所存儲(chǔ)的元素個(gè)數(shù)不比桶數(shù)大太多,插入、刪除和查找操作都能在常量時(shí)間內(nèi)運(yùn)行。</p><p> Hashmap也存儲(chǔ)鍵/值對(duì),它提供的操作與map幾乎一樣,這個(gè)hashmap實(shí)現(xiàn)使用鏈?zhǔn)缴⒘校ㄒ卜Q開(kāi)放散列),而且沒(méi)有提供諸如再散列等高級(jí)操作。</p><p><b> 程序?qū)崿F(xiàn)<
4、/b></p><p> Hashmap的訪問(wèn)操作:</p><p> 標(biāo)準(zhǔn)要求為鍵比較和值比較對(duì)象提供訪問(wèn)方法:</p><p> Operator[]與STL中的map的原型相似。如果原來(lái)的hashmap中沒(méi)有該鍵對(duì)應(yīng)的值,則會(huì)插入一個(gè),它會(huì)調(diào)用被映射的元素的默認(rèn)構(gòu)造函數(shù)進(jìn)行填充,并且反回這個(gè)值。</p><p><b&
5、gt; 模板的分離編譯:</b></p><p> 在模板類的聲明文件(一般是.h文件)的最后添加一個(gè)include語(yǔ)句,將模板類的實(shí)現(xiàn)文件包含進(jìn)來(lái),例如:</p><p> #include “template_class_implement.cpp”</p><p> 將模板類的實(shí)現(xiàn)類文件從項(xiàng)目中移除(使工程中不含模板的實(shí)現(xiàn)文件 .cpp),
6、但并不從磁盤(pán)上移除,不改變其路徑。使它不能顯示的參與編譯。</p><p> 在聲明main函數(shù)的文件中包含要使用的模板類的聲明文件。</p><p><b> 設(shè)計(jì)模式</b></p><p><b> 相關(guān)內(nèi)容</b></p><p> 1、Hashmap應(yīng)當(dāng)允許客戶指定自己的散列函數(shù)和
7、桶數(shù),而針對(duì)特定工作負(fù)載制定散列行為。另一方面,客戶如果沒(méi)有這種需求,或者沒(méi)有能力來(lái)編寫(xiě)一個(gè)好的散列函數(shù)及選擇桶數(shù),也應(yīng)該能夠不做任何定制地直接使用容器。一種解決方案是允許客戶在hashmap構(gòu)造函數(shù)中提供散列函數(shù)和桶數(shù),并為之提供默認(rèn)值。另外,把散列函數(shù)和桶數(shù)包裝在一個(gè)散列類中也是一種合理的做法:</p><p> Hash()的實(shí)現(xiàn)要難一些,部分原因在于它必須應(yīng)用于任何類型的鍵,它要把鍵映射至某個(gè)mNumB
8、uckets桶。此函數(shù)使用了除留余數(shù)法來(lái)完成散列,即鍵所對(duì)應(yīng)的桶(號(hào))是鍵對(duì)桶數(shù)取余后得到的一個(gè)整數(shù)值。</p><p> 遺憾的是,前面的方法無(wú)法應(yīng)用于string,因?yàn)椴煌膕tring對(duì)象可能包含相同的string值。因此相同的string值就可能散列到不同的桶中。這樣一來(lái),可以想到,專門針對(duì)string提供DefaultHash類的一個(gè)部分特殊化。</p><p> 2、它支持
9、3個(gè)基本操作:插入、刪除、查找。</p><p> 比較器:hashmap允許客戶指定比較類型作為模板參數(shù),并且能在構(gòu)造函數(shù)中傳遞該類的一個(gè)特定比較對(duì)象。Hashmap不會(huì)按鍵對(duì)元素排序,而是必須比較鍵的相等性。因此,它使用的是equal_to,比較對(duì)象只是用于檢測(cè)是否試圖向容器中插入重復(fù)鍵。</p><p> 散列器:允許客戶定義自己的類,以便構(gòu)造此類對(duì)象傳入構(gòu)造函數(shù),此時(shí)必須明確如
10、何在構(gòu)造函數(shù)中指定該參數(shù)的類型。</p><p> 散列模板參數(shù):使用 typedef 定義:</p><p> 鍵類型,值類型,比較類型,散列類型</p><p> 3、基本散列表結(jié)構(gòu)通常包括固定數(shù)目桶,每個(gè)桶可以存儲(chǔ)一個(gè)或多個(gè)元素。應(yīng)當(dāng)能夠基于一個(gè)bucket-id在常量時(shí)間內(nèi)訪問(wèn)桶。因此vector是對(duì)桶最為適合的容器。每個(gè)桶必須存儲(chǔ)一個(gè)元素列表,因此S
11、TL list可以用作桶類型。</p><p> 查找操作使用findElement幫助完成查找工作:findElement()首先使用散列對(duì)象將鍵散列至一個(gè)特定的桶。然后,在該桶中查找是否有元素的鍵與給定鍵匹配。所存儲(chǔ)的元素是鍵/值對(duì),所以具體的比較會(huì)在元素第一個(gè)字段上進(jìn)行。構(gòu)造函數(shù)中指定的比較函數(shù)對(duì)象就是用于完成這個(gè)比較。List需要完成線性查找來(lái)尋找匹配的元素,因此可以使用find()算法而不是一個(gè)顯式的
12、for循環(huán)。</p><p> Insert操作必須首先檢查hashmap中是否已經(jīng)存在此鍵的元素。如果沒(méi)有,會(huì)把元素插入到適當(dāng)?shù)耐爸械膌ist。需要說(shuō)明,findElement()會(huì)按引用返回散列到的那個(gè)桶,即在該桶中并沒(méi)有找到此鍵的元素。</p><p> 將hashmap作為容器</p><p> 有關(guān)typedef 的容器需求</p>&
13、lt;p> 作為容器必須提供的方法:</p><p><b> 編寫(xiě)一個(gè)迭代器:</b></p><p> 迭代器一般應(yīng)當(dāng)是一個(gè)看上去像智能指針的類,它要提供重載operator *和 operator ->,另外根據(jù)其特定行為還要提供其他一些操作。只要迭代器可以提供基本的迭代操作,應(yīng)該就能一切正常了。</p><p> H
14、ashIterator類:</p><p> 每個(gè)HashIterator對(duì)象都是hashmap類的一特定貨柜的迭代器。為了提供這種一對(duì)一的映射,HashIterator還必須是一個(gè)類模板,要針對(duì)hashmap類的同樣參數(shù)模板化。</p><p> Iterator_traits是一個(gè)類模板,它為各個(gè)迭代器類型定義了5個(gè)typedef。如果愿意,可以為你的新迭代器類型對(duì)其部分特殊化。還
15、有一種做法,iterator_traits類模板的默認(rèn)實(shí)現(xiàn)只是把這5個(gè)typedef從迭代器類本身當(dāng)中取出。因此可以直接在迭代器類中定義這些typedef。事實(shí)上,C++中的iterator類模板,它會(huì)提供typedef。這樣只需指定迭迭代器類型和元素類型作為模板參數(shù)提供給iterator類模板HashIterator是一個(gè)雙向迭代器,所以可以指定bidirectional_iterator_tag作為迭代器類型。元素類型就是pair&
16、lt;const Key,T></p><p> 可以不顯示地實(shí)現(xiàn)拷貝構(gòu)造函數(shù)和賦值操作符,因?yàn)槟J(rèn)的行為就是我們想要的。</p><p> 對(duì)于一個(gè)HashIterator自增會(huì)讓它指示容器中的“下一個(gè)”元素。這個(gè)方法首先讓list迭代器自新加增,然后檢查是否到達(dá)桶的末尾。倘若如此,就錄找hashmap中的下一個(gè)非控桶,因?yàn)橄乱粋€(gè)桶中可以沒(méi)有任何元素。如果沒(méi)有更多的非空桶,mI
17、t會(huì)設(shè)置為hashmap中最后一個(gè)桶的末尾迭代器,這是Hashmap的特殊“末尾”位置。應(yīng)當(dāng)記得,迭代器不必比啞指針更安全,所以對(duì)于已經(jīng)處在末尾的迭代器再自增等情況不必進(jìn)行錯(cuò)誤檢查。</p><p> 自減是自增的逆操作,它使迭代器指示容器中的“前一個(gè)”元素。不過(guò),在此存在非對(duì)稱性,自減算法首先檢查底層list迭代器是否是當(dāng)前桶的開(kāi)始迭代器。如果不是就可以自減。否則,代碼要檢查當(dāng)前桶之前的第一個(gè)非空桶。如果找到
18、了這樣一個(gè)非空桶,list迭代器必須設(shè)置為指示桶中的最后一個(gè)元素,即對(duì)末尾迭代器減1。如果沒(méi)有找到非空桶,自減就是非法的,所以代碼的行為是未定義的。</p><p> 在實(shí)現(xiàn)中,increment()和decrement()都訪問(wèn)了hashmap類的protected成員。因此,hashmap類必HashIterator是一個(gè)friend類。</p><p> Const迭代器:對(duì)元素
19、提供只讀訪問(wèn)。</p><p> 迭代器typedef和訪問(wèn)方法:</p><p> Begin() end():如果散列表中沒(méi)有元素就可返回末尾迭代器。</p><p> 關(guān)聯(lián)容器的typedef需求:</p><p> 我們的實(shí)現(xiàn)還包括一個(gè)mapped_type 的typedef,因?yàn)閙ap容器就提供了這樣一個(gè)typedef。Va
20、lue_compare并沒(méi)有實(shí)現(xiàn)為一個(gè)typedef,而是作為一個(gè)嵌套類定義??梢砸圆捎昧硗庖环N做法,此類可以是hashmap的一個(gè)friend類,但這個(gè)定義要遵循標(biāo)準(zhǔn)中所給出的map定義。Value_compare類的用途是對(duì)兩個(gè)元素的鍵調(diào)用比較函數(shù)。</p><p><b> 關(guān)聯(lián)容器的方法需求</b></p><p> 重載自增和自減操作:</p>
21、;<p> 不帶參數(shù)的為前綴版本,帶int參數(shù)的為后綴版本</p><p><b> 源代碼</b></p><p> //DefaultHash.h</p><p> #ifndef DEFAULTHASH_H</p><p> #define DEFAULTHASH_H</p>
22、<p> #include <string></p><p> #include <stdexcept></p><p> using namespace std;</p><p> template<typename T></p><p> class DefaultHash</
23、p><p><b> {</b></p><p><b> public:</b></p><p> /** Default constructor */</p><p> DefaultHash(int numBucket=101) throw (invalid_argument);</
24、p><p> int hash(const T& key) const;</p><p> int numBuckets() const {return mNumBuckets;}</p><p> /** Default destructor */</p><p> virtual ~DefaultHash();</p&g
25、t;<p> protected:</p><p> int mNumBuckets;</p><p><b> };</b></p><p> template<></p><p> class DefaultHash<string></p><p&g
26、t;<b> {</b></p><p><b> public:</b></p><p> DefaultHash(int numBuckets=101) throw (invalid_argument);</p><p> int hash(const string& key) const;</p
27、><p> int numBuckets() const {return mNumBuckets;}</p><p> protected:</p><p> int mNumBuckets;</p><p><b> };</b></p><p> #include "Defau
28、ltHash.cpp"</p><p> #endif // DEFAULTHASH_H</p><p> //HashIterator.h</p><p> #ifndef HASHITERATOR_H</p><p> #define HASHITERATOR_H</p><p> #inclu
29、de <vector></p><p> #include <list></p><p> #include <iterator></p><p> using namespace std;</p><p><b> //前向引用聲明</b></p><p&
30、gt; template <typename Key,typename T,typename Compare,typename Hash></p><p> class hashmap;</p><p><b> /**</b></p><p> * \class HashIterator</p><p&
31、gt; * \tparam Key 鍵類型</p><p> * \tparam T 要映射的類型</p><p> * \tparam Compare 比較器</p><p> * \tparam Hash hash函數(shù)</p><p> * \extends std::iterator</p><p>&
32、lt;b> */</b></p><p> template <typename Key,typename T,typename Compare,typename Hash></p><p> class HashIterator:public std::iterator<std::bidirectional_iterator_tag,pair&l
33、t;const Key,T> ></p><p><b> {</b></p><p> friend class hashmap<Key, T, Compare, Hash>;/*! a friend class*/</p><p><b> public:</b></p>&
34、lt;p> HashIterator();/**< Default constructor */</p><p> HashIterator(int bucket,typename list<pair<const Key,T> >::iterator listIt,</p><p> const hashmap<Key,T,Compare,H
35、ash>* inHashmap);/**< overload constructor */</p><p> pair<const Key,T>& operator*() const; /**< an overload operator *.Details.*/</p><p> pair<const Key,T>* operator
36、->() const;/**< an overload operator ->.Details.*/</p><p> HashIterator<Key,T,Compare,Hash>& operator++();</p><p> const HashIterator<Key,T,Compare,Hash> operator++(in
37、t);</p><p> HashIterator<Key,T,Compare,Hash>& operator--();</p><p> const HashIterator<Key,T,Compare,Hash> operator--(int);</p><p> bool operator==(const HashIter
38、ator& rhs) const;</p><p> bool operator!=(const HashIterator& rhs) const;</p><p> ~HashIterator();</p><p> protected:</p><p> int mBucket;</p><p&
39、gt; typename list<pair<const Key,T> >::iterator mIt;</p><p> const hashmap<Key,T,Compare,Hash>* mHashmap;</p><p> void increment();</p><p> void decrement();&l
40、t;/p><p><b> };</b></p><p> #include "HashIterator.cpp"</p><p> #endif // HASHITERATOR_H</p><p> //hashmap.h</p><p> #ifndef HASHMA
41、P_H</p><p> #define HASHMAP_H</p><p> #include "DefaultHash.h"</p><p> #include <list></p><p> #include <vector></p><p> #includ
42、e <stdexcept></p><p> #include "HashIterator.h"</p><p> using namespace std;</p><p> template <typename Key,typename T,typename Compare,typename Hash></p
43、><p> class HashIterator;</p><p><b> /**</b></p><p> * \class hashmap</p><p> * \tparam <Key>{鍵類型}</p><p> * \tparam <T> {要映射的類型}
44、</p><p> * \tparam <Compare> {比較器}</p><p> * \tparam <Hash> {hash函數(shù)}</p><p> * \extends std::iterator</p><p><b> */</b></p><p>
45、 template<typename Key,typename T,typename Compare=std::equal_to<Key>,</p><p> typename Hash=DefaultHash<Key> ></p><p> class hashmap</p><p><b> {</b&
46、gt;</p><p><b> public:</b></p><p><b> /**</b></p><p> * \var typedef Key key_type</p><p> * \brief 鍵類型</p><p><b> */<
47、/b></p><p> typedef Key key_type;</p><p><b> /**</b></p><p> * \var typedef T mapped_type</p><p> * \brief 被映射的元素類型</p><p><b> */
48、</b></p><p> typedef T mapped_type;</p><p><b> /**</b></p><p> * \var typedef pair<const Key,T> value_type</p><p> * \brief 值類型</p>&
49、lt;p><b> */</b></p><p> typedef pair<const Key,T> value_type;</p><p><b> /**</b></p><p> * \var typedef pair<const Key,T> reference</p&
50、gt;<p> * \brief 值的引用類型</p><p><b> */</b></p><p> typedef pair<const Key,T>& reference;</p><p><b> /**</b></p><p> * \var
51、typedef pair<const Key,T> const_reference</p><p> * \brief 只讀的值的引用類型</p><p><b> */</b></p><p> typedef const pair<const Key,T>& const_reference;</p
52、><p><b> /**</b></p><p> * \var typedef size_t size_type</p><p> * \brief 元素的大小類型</p><p><b> */</b></p><p> typedef size_t size_t
53、ype;</p><p><b> /**</b></p><p> * \var typedef ptrdiff_t difference_type</p><p> * \brief 元素的指針運(yùn)算結(jié)果類型</p><p><b> */</b></p><p>
54、 typedef ptrdiff_t difference_type;</p><p><b> /**</b></p><p> * \var typedef HashIterator<Key,T,Compare,Hash> iterator</p><p> * \brief 元素的迭代器類型</p>&l
55、t;p><b> */</b></p><p> typedef HashIterator<Key,T,Compare,Hash> iterator;</p><p> typedef HashIterator<Key,T,Compare,Hash> const_iterator;</p><p><b
56、> /**</b></p><p> * \class value_compare</p><p> * \extends binary_function</p><p> * \brief 用于比較兩個(gè)value_type的類</p><p> * 關(guān)聯(lián)容器需要定義這個(gè)類</p><p>
57、<b> */</b></p><p> class value_compare:public binary_function<value_type,value_type,bool></p><p><b> {</b></p><p> friend class hashmap<Key,T,Co
58、mpare,Hash>;</p><p><b> public:</b></p><p> bool operator()(const value_type& x,const value_type& y)const</p><p><b> {</b></p><p>
59、 return comp(x.first,y.first);</p><p><b> }</b></p><p> protected:</p><p> Compare comp;</p><p> value_compare(Compare c):comp(c){}</p><p>
60、;<b> };</b></p><p> friend class HashIterator<Key, T, Compare, Hash>;</p><p> iterator begin();</p><p> iterator end();</p><p> const_iterator be
61、gin() const;</p><p> const_iterator end() const;</p><p> typedef Compare key_compare;</p><p> /**< brief overload constructor*/</p><p> explicit hashmap(const Co
62、mpare& com=Compare(),const Hash& hash=Hash())</p><p> throw (invalid_argument);</p><p> /**< a template method as constructor */</p><p> template<class InputIterato
63、r></p><p> hashmap(InputIterator first,InputIterator last,</p><p> const Compare& comp=Compare(),const Hash& hash=Hash())</p><p> throw (invalid_argument);</p>
64、<p> /**< deconstructor */</p><p> ~hashmap();</p><p> /**< copy constructor */</p><p> hashmap(const hashmap<Key,T,Compare,Hash>& src);</p><p>
65、; /**< assignment operator */</p><p> hashmap<Key,T,Compare,Hash>& operator=(</p><p> const hashmap<Key,T,Compare,Hash>& rhs);</p><p> /**size method*/<
66、;/p><p> bool empty() const;</p><p> size_type size() const;</p><p> size_type max_size() const;</p><p> /** element operations */</p><p> T& operato
67、r[](const key_type& x);</p><p> pair<iterator,bool> insert(const value_type& x);</p><p> iterator insert(iterator position,const value_type& x);</p><p> templat
68、e<class InputIterator></p><p> void insert(InputIterator first,InputIterator last);</p><p> void erase(iterator position);</p><p> size_type erase(const key_type& x);&l
69、t;/p><p> void erase(iterator first,iterator last);</p><p> /**< other modify methods */</p><p> void swap(hashmap<Key,T,Compare,Hash>& hashIn);</p><p> v
70、oid clear();</p><p> /**< access method for STL conformity*/</p><p> key_compare key_comp() const;</p><p> value_compare value_comp() const;</p><p> /**< Look
71、up Methods*/</p><p> iterator find(const key_type& x);</p><p> const_iterator find(const key_type& x) const;</p><p> size_type count(const key_type& x) const;</p&g
72、t;<p> protected:</p><p> typename list<pair<const Key,T> >::iterator</p><p> findElement(const key_type& x,int& bucket) const;</p><p> typedef list&l
73、t;value_type> ListType;</p><p> vector<ListType>* mElems;</p><p> int mSize;</p><p> Compare mComp;</p><p> Hash mHash;</p><p><b> };&l
74、t;/b></p><p> #include "hashmap.cpp"</p><p> #endif // HASHMAP_H</p><p><b> 問(wèn)題分析</b></p><p><b> 總結(jié)</b></p><p><
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫(kù)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 軟件工程課程設(shè)計(jì)小論文之軟件設(shè)計(jì)
- c_課程設(shè)計(jì)---模擬抽獎(jiǎng)軟件設(shè)計(jì)
- 課程設(shè)計(jì)報(bào)告--純軟件設(shè)計(jì)出題程序
- 軟件設(shè)計(jì)課程設(shè)計(jì)---圖書(shū)管理系統(tǒng)設(shè)計(jì)
- c#課程設(shè)計(jì)—模擬抽獎(jiǎng)軟件設(shè)計(jì)
- 課程設(shè)計(jì)--超市庫(kù)存管理軟件設(shè)計(jì)
- c-課程設(shè)計(jì)—模擬抽獎(jiǎng)軟件設(shè)計(jì)
- java課程設(shè)計(jì)報(bào)告----計(jì)算器軟件設(shè)計(jì)
- 產(chǎn)品供貨商維護(hù)軟件設(shè)計(jì)課程設(shè)計(jì)
- c_課程設(shè)計(jì)—備忘錄軟件設(shè)計(jì)
- c_課程設(shè)計(jì)--—個(gè)人單詞薄軟件設(shè)計(jì)
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)論文-基礎(chǔ)軟件設(shè)計(jì)
- 圖像處理課程設(shè)計(jì)-- 圖像特征提取軟件設(shè)計(jì)
- 《軟件設(shè)計(jì)基礎(chǔ)(vb)》課程設(shè)計(jì)-- rtf編輯器
- 《軟件設(shè)計(jì)基礎(chǔ)(c++)》課程設(shè)計(jì)報(bào)告書(shū)
- c_課程設(shè)計(jì)——自助取款機(jī)軟件設(shè)計(jì)
- 課程設(shè)計(jì)---常用功能計(jì)算器軟件設(shè)計(jì)
- 《基于android的簡(jiǎn)單聊天通信軟件設(shè)計(jì)》課程設(shè)計(jì)報(bào)告
- c_課程設(shè)計(jì)—自動(dòng)取款機(jī)模擬軟件設(shè)計(jì)
- java課程設(shè)計(jì)--基于java的掃雷游戲軟件設(shè)計(jì)
評(píng)論
0/150
提交評(píng)論