⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 __hash.h

📁 A Set of Simple C++ Hash Templates
💻 H
📖 第 1 页 / 共 2 页
字号:
			return m_pListElement->m_element;		}		/**		 *   \brief See operator *()		 */		T *operator ->() {			return &(operator*());		}		/**		 *   \brief Compares 2 iterators. 		 * @param p The 2nd iterator		 * @return TRUE if the iterators are equal or both have m_bEnd set, FALSE otherwise.		 */		bool operator ==(const hasherator &p) const {			return m_pListElement == p.m_pListElement;		}		/**		 *   \brief Is this the past-the-end iterator.		 			Call this member after you have incremented the iterator and want to know if you have reached the end of the hash table.		 * @return TRUE if this iterator points past the end of the hash table, FALSE otherwise.		 */		inline bool IsEnd() const {return m_pListElement == NULL;}	protected:		bucket_array *m_pbuckets;//!<Points to the pointer array in the hash table.				bucket_array_unit m_nBucketIndex;//!<Index of the pointer array that this iterator is currently pointing to.		listelement *m_pListElement;//!<pointer to the list element the iterator is pointing to	};		//!A iterator pointing to a constant hash	class const_hasherator {	public:		//!Simple constructor		/**You can't use this hasherator using this, unless it gets assigned by another one, which was constructed with another constructor*/		const_hasherator() {			#ifndef NDEBUG				m_pbuckets = NULL;				m_pListElement = NULL;			#endif		}		/**		 * \brief Constructor		 * @param buckets The bucket array		 */		const_hasherator(const bucket_array &buckets);			/**		 *   \brief Pre-increment operator		 * @return The hash iterator before incrementing		 */		const_hasherator &operator++();		/**		 *   \brief Dereferences the member of the hash table pointed to by the iterator		 * @return A reference to the member of the hash table.		 */		const T &operator *() const {			assert(m_pListElement != NULL);			return m_pListElement->m_element;		}		/**		 *   \brief See operator *()		 */		const T *operator ->() const {			return &(operator*());		}		/**		 *   \brief Compares 2 iterators. 		 * @param iter The 2nd iterator		 * @return TRUE if the iterators are equal or both have m_bEnd set, FALSE otherwise.		 */		bool operator ==(const const_hasherator &iter) const {			return m_pListElement == iter.m_pListElement;		}		/**		 *   \brief Is the the past-the-end iterator.		 			Call this member after you have incremented the iterator and want to know if you have reached the end of the hash table.		 * @return TRUE if this iterator points past the end of the hash table, FALSE otherwise.		 */		bool IsEnd() const {return m_pListElement == NULL;}	protected:		//bool m_bEnd;//!<TRUE if this iterator points past-the-end of the hash table, FALSE otherwise		//typedef const bucket_array * cbucket_array_ptr;		const bucket_array *m_pbuckets;//!<Points to the pointer array in the hash table.		bucket_array_unit m_nBucketIndex;//!<Index of the pointer array that this iterator is currently pointing to.		const listelement *m_pListElement;//!<pointer to the list element the iterator is pointing to		//const hashelementlist *m_plist;//!<The STL list that this iterator is pointing to.	};	/**	 *  \brief Gets the first reference in the hash table	 * @return Iterator to the first member of the hash table	 */	hasherator begin() {		hasherator iter(__hash<T>::m_buckets);		return iter;	}	/**	 *  \brief Gets the first reference in the hash table	 * @return An iterator to the first member of a constant hash table.	 */	const_hasherator begin() const {		const_hasherator iter(__hash<T>::m_buckets);		return iter;	}	/*!		\fn __hash::Delete		\brief Removes all elements from the table and clears the bucket array	*/	void Delete() {		m_buckets.clear();		m_nCount = 0;	}protected:	/**	 *  \brief Gets the list in which the sought element is to be found.			This should call your hashing function.	 * @param  ref An instance of T which has the member used to reference.	 * @return The index for m_buckets of the element that has the list. This reference should be >= 0 and \< GetBucketSize().	 	\note <b>Do not neglect to include the HASHREFERENCEPREATTRIBUTES and HASHREFERENCEPOSTATTRIBUTES parts.</b> If you do, you probably won't get a compile or linker error, but your program will behave unpredictably.	 */	virtual bucket_array_unit HASHREFERENCEPREATTRIBUTES GetHashReference(const T &ref) const HASHREFERENCEPOSTATTRIBUTES =0;};template <typename T>T &__hash<T>::Add(const T &def) {	assert(m_buckets.size() > 0);	bucket_array_unit nIndex = GetHashReference(def);	assert(nIndex < m_buckets.size());	hashelementlist &alist = m_buckets[nIndex];	alist.push_back(def);	m_nCount++;	return alist.back();}template <typename T>void __hash<T>::clear() {	bucket_array_unit nSize = m_buckets.size();	for (bucket_array_unit nIndex = 0; nIndex < nSize; nIndex++) {		m_buckets[nIndex].clear();	}	m_nCount = 0;}/*!    \fn __hash<T>::TakeArray(const std::vector<T> &array)    \brief Method that takes an array and incorporates it into the hash    Any current elements in the hash are cleared. The bucket array does not change. */template <typename T>void __hash<T>::TakeArray(const std::vector<T> &array) {	clear();	bucket_array_unit nSize = array.size();	SetBucketSize(nSize);	for (bucket_array_unit nIndex = 0; nIndex < nSize; nIndex++)		Add(array[nIndex]);}//!Takes the contents and put thems into an array.template <typename T>typename __hash<T>::bucket_array_unit __hash<T>::GetArray(std::vector<T> &array) const {	array.clear();	const bucket_array &table = __hash<T>::m_buckets;	bucket_array_unit nSize = table.size();	for (bucket_array_unit nTableIndex = 0; nTableIndex < nSize; nTableIndex++) {		for(const listelement *pElement = table[nTableIndex].head(); pElement != NULL; pElement = pElement->next())			array.push_back(pElement->m_element);	}	return array.size();}template <typename T>__hash<T>::listelement::listelement(const listelement &le) : m_element(le.m_element) {	if (le.m_pNext == NULL) m_pNext = NULL;	else {		m_pNext = new listelement(*le.m_pNext);		m_pNext->m_pPrev = this;	}	if (le.m_pPrev == NULL) m_pPrev = NULL;//if not, our m_pPrev will be set by the previous instance}template <typename T>__hash<T>::listelement::listelement(listelement *pPrev, listelement *pNext, const T &element) : m_element(element), m_pPrev(pPrev), m_pNext(pNext) {	if (m_pPrev != NULL) {		assert(m_pPrev->m_pNext == pNext);		m_pPrev->m_pNext = this;	}	if (m_pNext != NULL) {		assert(m_pNext->m_pPrev == pPrev);		m_pNext->m_pPrev = this;	}	CHECK_NEXT_AND_PREV();}template <typename T>__hash<T>::elementlist::elementlist(const T &t) {	#ifdef DEBUG_AHASH		m_nSize = 1;	#endif	m_plist = new listelement(NULL, NULL, t);	assert(m_plist->m_pPrev == NULL);	m_ptail = m_plist;	#ifdef DEBUG_AHASH		assert(SizeCorrect());		assert(m_plist->CheckNextAndPrev());	#endif}template <typename T>typename __hash<T>::listelement *__hash<T>::elementlist::push_back(const T &element) {	#ifdef DEBUG_AHASH		assert(m_plist == NULL || m_plist->CheckNextAndPrev());		m_nSize++;	#endif	listelement *pNew = new listelement(m_ptail, NULL, element);	if (m_plist == NULL) {		assert(m_ptail == NULL);		m_plist = pNew;	}	else assert(m_ptail != NULL);	m_ptail = pNew;	assert(m_ptail->next() == NULL);	#ifdef DEBUG_AHASH		assert(SizeCorrect());		assert(m_plist == NULL || m_plist->CheckNextAndPrev());	#endif	return pNew;}template <typename T>void __hash<T>::elementlist::clear() {	#ifdef DEBUG_AHASH		assert(m_plist == NULL || m_plist->CheckNextAndPrev());assert(BothNULLorNonNULL());assert(SizeCorrect());	#endif	if (m_plist != NULL) {delete m_plist; m_plist = NULL;m_ptail = NULL;		#ifdef DEBUG_AHASH			m_nSize = 0;		#endif	}	#ifdef DEBUG_AHASH		assert(SizeCorrect());	#endif}template <typename T>size_t __hash<T>::elementlist::size() const {	size_t nSize = 0;	const listelement *le = m_plist;	if (le != NULL) {		assert(le->prev() == NULL);	}	for (const listelement *p = le; p != NULL; p = p->next()) {		nSize++;		assert((p->next() == NULL) == (p == m_ptail));	}	return nSize;}template <typename T>void __hash<T>::elementlist::Destroy() {	#ifdef DEBUG_AHASH		assert(BothNULLorNonNULL());		assert(m_plist == NULL || m_plist->CheckNextAndPrev());		assert(SizeCorrect());	#endif	for (listelement *pCurrent = m_ptail; pCurrent != NULL;) {		listelement *pCurrentActual = pCurrent;		pCurrent = pCurrent->m_pPrev;		if (pCurrent != NULL)			pCurrent->m_pNext = NULL;		delete pCurrentActual;	}	#ifdef DEBUG_AHASH		m_nSize = 0;	#endif	m_plist = NULL;	m_ptail = NULL;}template <typename T>void __hash<T>::elementlist::Copy(const elementlist &el) {	Destroy();	if (el.m_plist == NULL) {		m_plist = NULL;		assert(el.m_ptail == NULL);		m_ptail = NULL;		#ifdef DEBUG_AHASH			m_nSize = 0;		#endif	}	else {		m_plist = new listelement(*el.m_plist);		assert(m_plist->m_pPrev == NULL);		#ifdef DEBUG_AHASH			m_nSize = 1;		#endif		for (m_ptail = m_plist; m_ptail->next() != NULL; m_ptail = m_ptail->next()) {			#ifdef DEBUG_AHASH				m_nSize++;			#endif		}	}}template <typename T>__hash<T>::hasherator::hasherator(bucket_array &buckets) : m_pbuckets(&buckets), m_pListElement(NULL) {	bucket_array_unit nSize = m_pbuckets->size();	for (m_nBucketIndex = 0; m_nBucketIndex < nSize; m_nBucketIndex++) {		elementlist &list = m_pbuckets->at(m_nBucketIndex);		if (!list.empty()) {			m_pListElement = list.head();			break;		}	}}template <typename T>typename __hash<T>::hasherator &__hash<T>::hasherator::operator++() {//pre-increment	if (m_pListElement != NULL) {		assert(m_pbuckets != NULL);		if ((m_pListElement = m_pListElement->next()) == NULL) {			bucket_array_unit nSize = m_pbuckets->size();			while (++m_nBucketIndex < nSize) {				bucket_array &table = *m_pbuckets;				if (!table.at(m_nBucketIndex).empty()) {					elementlist &the_list = table[m_nBucketIndex];					m_pListElement = the_list.head();					break;				}			}		}	}	return *this;}template <typename T>__hash<T>::const_hasherator::const_hasherator(const bucket_array &buckets) : m_pbuckets(&buckets), m_pListElement(NULL) {	bucket_array_unit nSize = m_pbuckets->size();	for (m_nBucketIndex = 0; m_nBucketIndex < nSize; m_nBucketIndex++) {		const elementlist &list = m_pbuckets->at(m_nBucketIndex);		if (!list.empty()) {			m_pListElement = list.head();			break;		}	}}template <typename T>typename __hash<T>::const_hasherator &__hash<T>::const_hasherator::operator++() {//pre-increment	if (m_pListElement != NULL) {		assert(m_pbuckets != NULL);		if ((m_pListElement = m_pListElement->next()) == NULL) {			bucket_array_unit nSize = m_pbuckets->size();			while (++m_nBucketIndex < nSize) {				const bucket_array &table = *m_pbuckets;				if (!table.at(m_nBucketIndex).empty()) {					const elementlist &the_list = table[m_nBucketIndex];					m_pListElement = the_list.head();					break;				}			}		}	}	return *this;}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -