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

📄 xhash

📁 C语言库函数的原型,有用的拿去
💻
📖 第 1 页 / 共 2 页
字号:
		return (_Max_bucket_size);
		}

	void max_load_factor(float _Newmax)
		{	// set new load factor
		if (_Newmax != _Newmax	// may detect a NaN
			|| _Newmax < 0)
			_STD _Xout_of_range("invalid hash load factor");

		_Max_bucket_size = _Newmax;
		}

	void rehash(size_type _Buckets)
		{	// rebuild table with at least _Buckets buckets
		size_type _Maxsize = _Vec.max_size() / 4;
		size_type _Newsize = _Min_buckets;

		for (; _Newsize < _Buckets && _Newsize < _Maxsize; )
			_Newsize *= 2;	// double until big enough
		if (_Newsize < _Buckets)
			_STD _Xout_of_range("invalid hash bucket count");
		for (float _Size = (float)size();
			max_load_factor() < _Size / _Newsize && _Newsize < _Maxsize; )
			_Newsize *= 2;	// double until load factor okay

		_Init(_Newsize);
		_Reinsert(end());
		}
// ADDED WITH TR1 -- END

	_Pairib insert(const value_type& _Val)
		{	// try to insert node with value _Val
		_List.push_front(_Val);
		return (_Insert(_Val, begin()));
		}

	iterator insert(const_iterator, const value_type& _Val)
		{	// try to insert node with value _Val, ignore hint
		return (insert(_Val).first);
		}

	template<class _Iter>
		void insert(_Iter _First, _Iter _Last)
		{	// insert [_First, _Last) at front, then put in place
		iterator _Oldlast = begin();
		_List.insert(begin(), _First, _Last);
		if (max_load_factor() < load_factor())
			rehash(bucket_count());
		else
			_Reinsert(_Oldlast);
		}

	iterator erase(const_iterator _Plist)
		{	// erase element at _Plist
		size_type _Bucket = _Hashval(this->_Kfn(*_Plist));

		_Erase_bucket(_List._Make_iter(_Plist), _Bucket);
		return (_List.erase(_Plist));
		}

	iterator erase(const_iterator _First, const_iterator _Last)
		{	// erase [_First, _Last)
		_DEBUG_RANGE(_First, _Last);
		if (_First == begin() && _Last == end())
			{	// erase all
			clear();
			return (begin());
			}
		else
			{	// partial erase, one at a time
			while (_First != _Last)
				erase(_First++);
			return (_List._Make_iter(_First));
			}
		}

	size_type erase(const key_type& _Keyval)
		{	// erase and count all that match _Keyval
		_Pairii _Where = equal_range(_Keyval);
		size_type _Num = 0;
		_Distance(_Where.first, _Where.second, _Num);
		erase(_Where.first, _Where.second);
		return (_Num);
		}

	void erase(const key_type *_First,
		const key_type *_Last)
		{	// erase all that match array of keys [_First, _Last)
		_DEBUG_RANGE(_First, _Last);
		for (; _First != _Last; ++_First)
			erase(*_First);
		}

	void clear()
		{	// erase all
		_List.clear();
		_Init();
		}

	iterator find(const key_type& _Keyval)
		{	// find an element in mutable hash table that matches _Keyval
		return (lower_bound(_Keyval));
		}

	const_iterator find(const key_type& _Keyval) const
		{	// find an element in nonmutable hash table that matches _Keyval
		return (lower_bound(_Keyval));
		}

	size_type count(const key_type& _Keyval) const
		{	// count all elements that match _Keyval
		_Paircc _Ans = equal_range(_Keyval);
		size_type _Num = 0;
		_Distance(_Ans.first, _Ans.second, _Num);
		return (_Num);
		}

	iterator lower_bound(const key_type& _Keyval)
		{	// find leftmost not less than _Keyval in mutable hash table
		size_type _Bucket = _Hashval(_Keyval);
		for (iterator _Where = _Begin(_Bucket);
			_Where != _End(_Bucket); ++_Where)
			if (!this->comp(this->_Kfn(*_Where), _Keyval))
				return (this->comp(_Keyval,
					this->_Kfn(*_Where)) ? end() : _Where);
		return (end());
		}

	const_iterator lower_bound(const key_type& _Keyval) const
		{	// find leftmost not less than _Keyval in nonmutable hash table
		size_type _Bucket = _Hashval(_Keyval);
		for (const_iterator _Where = _Begin(_Bucket);
			_Where != _End(_Bucket); ++_Where)
			if (!this->comp(this->_Kfn(*_Where), _Keyval))
				return (this->comp(_Keyval,
					this->_Kfn(*_Where)) ? end() : _Where);
		return (end());
		}

	iterator upper_bound(const key_type& _Keyval)
		{	// find leftmost not greater than _Keyval in mutable hash table
		size_type _Bucket = _Hashval(_Keyval);
		for (iterator _Where = _End(_Bucket);
			_Where != _Begin(_Bucket); )
			if (!this->comp(_Keyval, this->_Kfn(*--_Where)))
				return (this->comp(this->_Kfn(*_Where),
					_Keyval) ? end() : (iterator)++_Where);
		return (end());
		}

	const_iterator upper_bound(const key_type& _Keyval) const
		{	// find leftmost not greater than _Keyval in nonmutable hash table
		size_type _Bucket = _Hashval(_Keyval);
		for (const_iterator _Where = _End(_Bucket);
			_Where != _Begin(_Bucket); )
			if (!this->comp(_Keyval, this->_Kfn(*--_Where)))
				return (this->comp(this->_Kfn(*_Where),
					_Keyval) ? end() : (const_iterator)++_Where);
		return (end());
		}

	_Pairii equal_range(const key_type& _Keyval)
		{	// find range equivalent to _Keyval in mutable hash table
		size_type _Bucket = _Hashval(_Keyval);
		for (iterator _Where = _Begin(_Bucket);
			_Where != _End(_Bucket); ++_Where)
			if (!this->comp(this->_Kfn(*_Where), _Keyval))
				{	// found _First, look for end of range
				iterator _First = _Where;
				for (; _Where != _End(_Bucket); ++_Where)
					if (this->comp(_Keyval, this->_Kfn(*_Where)))
						break;
				if (_First == _Where)
					break;
				return (_Pairii(_First, _Where));
				}
		return (_Pairii(end(), end()));
		}

	_Paircc equal_range(const key_type& _Keyval) const
		{	// find range equivalent to _Keyval in nonmutable hash table
		size_type _Bucket = _Hashval(_Keyval);
		for (const_iterator _Where = _Begin(_Bucket);
			_Where != _End(_Bucket); ++_Where)
			if (!this->comp(this->_Kfn(*_Where), _Keyval))
				{	// found _First, look for end of range
				const_iterator _First = _Where;
				for (; _Where != _End(_Bucket); ++_Where)
					if (this->comp(_Keyval, this->_Kfn(*_Where)))
						break;
				if (_First == _Where)
					break;
				return (_Paircc(_First, _Where));
				}
		return (_Paircc(end(), end()));
		}

	void swap(_Myt& _Right)
		{	// exchange contents with _Right
		if (this != &_Right)
			{	// different, worth swapping
			_Swap_adl(this->comp, _Right.comp);
			this->_List.swap(_Right._List);
			this->_Vec.swap(_Right._Vec);
			_STD swap(this->_Mask, _Right._Mask);
			_STD swap(this->_Maxidx, _Right._Maxidx);
			_STD swap(this->_Max_bucket_size, _Right._Max_bucket_size);
			}
		}

protected:
	iterator& _Vec_lo(size_type _Bucket)
		{	// return reference to begin() for _Bucket
		return (_Vec[2 * _Bucket]);
		}

	const iterator& _Vec_lo(size_type _Bucket) const
		{	// return reference to begin() for _Bucket
		return (_Vec[2 * _Bucket]);
		}

	iterator& _Vec_hi(size_type _Bucket)
		{	// return reference to end()-1 for _Bucket
		return (_Vec[2 * _Bucket + 1]);
		}

	const iterator& _Vec_hi(size_type _Bucket) const
		{	// return reference to end()-1 for _Bucket
		return (_Vec[2 * _Bucket + 1]);
		}

	iterator _Begin(size_type _Bucket)
		{	// return begin iterator for bucket _Bucket
		return (_Vec_lo(_Bucket));
		}

	const_iterator _Begin(size_type _Bucket) const
		{	// return begin iterator for bucket _Bucket
		return (_Vec_lo(_Bucket));
		}

	iterator _End(size_type _Bucket)
		{	// return end iterator for bucket _Bucket
		if (_Vec_lo(_Bucket) == end())
			return (end());
		else
			{	// point past last element
			iterator _Ans = _Vec_hi(_Bucket);
			return (++_Ans);
			}
		}

	const_iterator _End(size_type _Bucket) const
		{	// return end iterator for bucket _Bucket
		if (_Vec_lo(_Bucket) == end())
			return (_List._Make_iter(end()));
		else
			{	// point past last element
			iterator _Ans = _Vec_hi(_Bucket);
			return (++_Ans);
			}
		}

	void _Erase_bucket(iterator _Plist, size_type _Bucket)
		{	// fix iterators before erasing _Plist before _Where
		if (_Vec_hi(_Bucket) == _Plist)
			if (_Vec_lo(_Bucket) == _Plist)
				{	// make bucket empty
				_Vec_lo(_Bucket) = end();
				_Vec_hi(_Bucket) = end();
				}
			else
				_Vec_hi(_Bucket) = --_Plist;	// move end back one element
		else if (_Vec_lo(_Bucket) == _Plist)
			_Vec_lo(_Bucket) = ++_Plist;	// move beginning up one element
		}

	void _Insert_bucket(iterator _Plist, iterator _Where,
		size_type _Bucket)
		{	// fix iterators after inserting _Plist before _Where
		if (_Vec_lo(_Bucket) == end())
			{	// make bucket non-empty
			_Vec_lo(_Bucket) = _Plist;
			_Vec_hi(_Bucket) = _Plist;
			}
		else if (_Vec_lo(_Bucket) == _Where)
			_Vec_lo(_Bucket) = _Plist;	// move beginning back one element
		else if (++_Vec_hi(_Bucket) != _Plist)	// move end up one element
			--_Vec_hi(_Bucket);	// or not
		}

	void _Copy(const _Myt& _Right)
		{	// copy entire hash table
		_Mask = _Right._Mask;
		_Maxidx = _Right._Maxidx;
		_Max_bucket_size = _Right._Max_bucket_size;
		_List.clear();

		_TRY_BEGIN
		_List.insert(end(), _Right.begin(), _Right.end());
		this->comp = _Right.comp;
		_CATCH_ALL
		_List.clear();	// list or compare copy failed, bail out
		_RERAISE;
		_CATCH_END

		_Vec.assign(_Right._Vec.size(), end());
		_Reinsert(end());
		}

	void _Grow()
		{	// grow hash table by one bucket
		if (_Vec.size() / 2 <= _Maxidx)
			{	// table full, double its size
			_Mask = _Vec.size() - 1;
			_Vec.insert(_Vec.end(), _Vec.size(), end());
			}
		else if (_Mask < _Maxidx)
			_Mask = (_Mask << 1) + 1;

		size_type _Bucket = _Maxidx - (_Mask >> 1) - 1;
		for (iterator _Plist = _Begin(_Bucket);
			_Plist != _End(_Bucket); )
			{	// split old bucket
			size_type _Newbucket =
				this->comp(this->_Kfn(*_Plist)) & _Mask;
			if (_Newbucket == _Bucket)
				++_Plist;	// leave element in old bucket

 #if _ITERATOR_DEBUG_LEVEL == 2
			else if (_Newbucket != _Maxidx)
				_DEBUG_ERROR("bad hash function");
 #endif /* _ITERATOR_DEBUG_LEVEL == 2 */

			else
				{	// move element to new bucket
				iterator _Where = _Plist;

				++_Where;
				_Erase_bucket(_Plist, _Bucket);
				_List._Splice_same(end(), _List, _Plist, _Where, 0);
				_Insert_bucket(_Plist, end(), _Newbucket);
				_Plist = _Where;
				}
			}
		++_Maxidx;	// open new bucket for hash lookup
		}

	size_type _Hashval(const key_type& _Keyval) const
		{	// return hash value, masked and wrapped to current table size
		size_type _Num = this->comp(_Keyval) & _Mask;
		if (_Maxidx <= _Num)
			_Num -= (_Mask >> 1) + 1;
		return (_Num);
		}

	void _Init(size_type _Buckets = _Min_buckets)
		{	// initialize hash table with _Buckets buckets, leave list alone
		_Vec.assign(2 * _Buckets, end());
		_Mask = _Buckets - 1;
		_Maxidx = _Buckets;
		}

	_Pairib _Insert(const value_type& _Val, iterator _Plist)
		{	// try to insert existing node with value _Val
		size_type _Bucket = _Hashval(this->_Kfn(_Val));
		iterator _Where = _End(_Bucket);

		for (; _Where != _Begin(_Bucket); )
			if (this->comp(this->_Kfn(_Val), this->_Kfn(*--_Where)))
				;	// still too high in bucket list
			else if (_Multi
				|| this->comp(this->_Kfn(*_Where), this->_Kfn(_Val)))
				{	// found insertion point, back up to it
				++_Where;
				break;
				}
			else
				{	// discard new list element and return existing
				_List.erase(_Plist);
				return (_Pairib(_Where, false));
				}

		iterator _Next = _Plist;
		if (_Where != ++_Next)
			_List._Splice_same(_Where, _List,
				_Plist, _Next, 1);	// move element into place

		_Insert_bucket(_Plist, _Where, _Bucket);
		_Check_size();
		return (_Pairib(_Plist, true));	// return iterator for new element
		}

	void _Check_size()
		{	// grow table as needed
		if (max_load_factor() < load_factor())

 #if _HAS_INCREMENTAL_HASH
			_Grow();	// too dense, need to grow hash table

 #else /* _HAS_INCREMENTAL_HASH */
			{	// rehash to bigger table
			size_type _Maxsize = _Vec.max_size() / 2;
			size_type _Newsize = bucket_count();

			for (int _Idx = 0; _Idx < 3 && _Newsize < _Maxsize; ++_Idx)
				_Newsize *= 2;	// multiply safely by 8
			_Init(_Newsize);
			_Reinsert(end());
			}
 #endif /* _HAS_INCREMENTAL_HASH */
		}

	void _Reinsert(iterator _Last)
		{	// insert elements in [begin(), _Last)
		if (begin() != _Last)
			for (--_Last; ; )
				{	// reinsert elements in [begin(), _Last]
				iterator _First = begin();
				bool _Done = _First == _Last;
				_Insert(*_First, _First);
				if (_Done)
					break;
				}
		}

	_Mylist _List;	// list of elements, must initialize before _Vec
	_Myvec _Vec;	// vector of list iterators, begin() then end()-1
	size_type _Mask;	// the key mask
	size_type _Maxidx;	// current maximum key value
	float _Max_bucket_size;	// current maximum bucket size
	};

		// _Hash TEMPLATE OPERATORS
template<class _Ty> inline
	bool operator==(const _Hash<_Ty>& _Left, const _Hash<_Ty>& _Right)
	{	// test for hash table equality
	return (_Left.size() == _Right.size()
		&& equal(_Left.begin(), _Left.end(), _Right.begin()));
	}

template<class _Ty> inline
	bool operator!=(const _Hash<_Ty>& _Left, const _Hash<_Ty>& _Right)
	{	// test for hash table inequality
	return (!(_Left == _Right));
	}

template<class _Ty> inline
	bool operator<(const _Hash<_Ty>& _Left, const _Hash<_Ty>& _Right)
	{	// test if _Left < _Right for hash tables
	return (lexicographical_compare(_Left.begin(), _Left.end(),
		_Right.begin(), _Right.end()));
	}

template<class _Ty> inline
	bool operator>(const _Hash<_Ty>& _Left, const _Hash<_Ty>& _Right)
	{	// test if _Left > _Right for hash tables
	return (_Right < _Left);
	}

template<class _Ty> inline
	bool operator<=(const _Hash<_Ty>& _Left, const _Hash<_Ty>& _Right)
	{	// test if _Left <= _Right for hash tables
	return (!(_Right < _Left));
	}

template<class _Ty> inline
	bool operator>=(const _Hash<_Ty>& _Left, const _Hash<_Ty>& _Right)
	{	// test if _Left >= _Right for hash tables
	return (!(_Left < _Right));
	}
_STD_END

 #pragma warning(pop)
 #pragma pack(pop)

#endif /* RC_INVOKED */
#endif /* _XHASH_ */

/*
 * Copyright (c) 1992-2009 by P.J. Plauger.  ALL RIGHTS RESERVED.
 * Consult your license regarding permissions and restrictions.
V5.20:0009 */

⌨️ 快捷键说明

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