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

📄 mjbitset.h

📁 cmjbitset_demo
💻 H
📖 第 1 页 / 共 3 页
字号:

						memmove(&m_pData[0], &m_pData[1], (m_len -1) * sizeof(_DATA));
						m_len --;
					
						_P -= c+1;
					
					}
				
				}
				// just one problem all top bits are now set
				_INDEX i = 0;
				_INDEX bit = 0;
				while (i < m_len);
				{
					bit += m_pData[i]; //unset bit

					bit++; // position after unset bit
					i++;
				}
				if (bit < _N-_P)
				{
					allocate(m_len+1);
					m_pData[m_len-1] = (_N- _P) - bit;
					bit = _N - _P +1;
				}
				while (bit < _N)
				{
					allocate(m_len+1);
					m_pData[m_len -1] = 0;
					bit++;

				}

			}


			break;
		}
		
#ifdef DEBUG_CMJBITSET
	
		_ASSERT((*this) == m_bitset);
#endif
		return (*this);
		
	}

	CMJBitset<_N >& operator<<=(size_t _P){
#ifdef DEBUG_CMJBITSET
		//fprintf(stderr,"CMJBitset::%s\n",this->to_string().c_str());
		_ASSERT((*this) == m_bitset);
		
#endif	
		if (!_P) return (*this);
		switch (m_type)
		{

		case BS_SPARSE:
			if (m_len == _N)
			{
				allocate(1);
				m_type = BS_FULL;
				m_pData[0] = _P-1;
			}
			else
			{
				m_pData[0] += _P;
				// remove overflow
				_INDEX bit = 0;
				for (_INDEX i = 0; i < m_len; i++)
				{
					bit += m_pData[i]  ;  // position of set bit
					if (bit >= _N)
					{
						m_len =i;
						break;
					}
					bit++;
				}
			}
			break;
		case BS_NORMAL:
			*(std::bitset<_N> *)m_pData<<=_P;
			break;
		case BS_FULL:
			if (m_len == 0){
				allocate(_P);
				memset(&m_pData[0], 0, m_len * sizeof(_DATA));
			}
			else 
			{
				//if (m_pData[0] + _P < _N)
				//{
					// remove overflow
					_INDEX bit = 0;
					for (_INDEX i = 0; i < m_len; i++)
					{
						bit += m_pData[i] ; // unset bit pos
						if (bit >= _N-_P)
						{
							m_len = i;;
							break;
						}
						bit++;
					}
					if (m_len + _P >= _N)
					{
						m_len = _N;
						
					}
					else
					{
						allocate(m_len +_P);
						memmove(&m_pData[_P], &m_pData[0], sizeof(_DATA) * (m_len - _P));
						memset(&m_pData[0], 0, _P *sizeof(_DATA));
					}
					//for (;bit < _N;bit++)
					//{
					//	reset_set_bit(bit);
					//}
				//}
				//else
				//{
				//	m_len = _N;
				//}

			}

			break;
	
		}
			
#ifdef DEBUG_CMJBITSET
		m_bitset <<= _P;
		_ASSERT((*this) == m_bitset);
	
#endif
		return (*this);
	}

	bool operator==(const bitset<_N>& _R) const {

		_INDEX count = this->count() ;
		if (count != _R.count()) {
#ifdef DEBUG_CMJBITSET
			//
			// example code of the type useful when regressing the CMJBitset class
			//
			int rc = _R.count();
			fprintf(stderr,"CMjBitset::%s\n",this->to_string().c_str());
			fprintf(stderr,"   Bitset::%s\n",this->m_bitset.to_string().c_str());
#endif
			return false;
		}

		if (count == 0 || count == _N) return true;

		switch (m_type)
		{
		case BS_SPARSE:
			{
			_INDEX bit=0;
			for (_INDEX i = 0; i < m_len; i++)
			{
				bit += m_pData[i];

				if (!_R.test(bit)){
					return false;
				}
				bit++;
			}
			}
			return true;
		case BS_NORMAL:
			{
			std::bitset<_N> *pL = (std::bitset<_N> *)m_pData;

			return *pL == _R;
			}
		case BS_FULL:
			{

			_INDEX bit=0;
			for (_INDEX i = 0; i < m_len; i++)
			{
				bit += m_pData[i];

				if (_R.test(bit)) {
					return false;
				}
				bit++;
			}

			return true;
			}
			

		}
		return false;
			
	}

	void make_sparse()
	{

		_ASSERT(m_type != BS_SPARSE);

		CMJBitset<_N> temp;
		switch (m_type)
		{
		case BS_NORMAL:
				{
				for (_INDEX i = 0; i < _N; i++)
				{
					if (test(i))
					{
						temp.set_unset_bit(i, false);
					}
				}
				break;
				}
			case BS_FULL:
				{
					_INDEX bit= 0;
					_INDEX set_bit = 0;
					_INDEX i = 0;
					while(i < m_len)
					{
						bit += m_pData[i]; // unset bit
						for (_INDEX j = set_bit; j < bit; j++)
						{
							temp.set_unset_bit(j, false);
						}
						bit++;
						set_bit = bit;
						i++;

					}
					for (_INDEX j = bit ; j < _N; j++)
					{
						for (_INDEX j = set_bit; j < bit; j++)
						{
							temp.set_unset_bit(j, false);
						}
					}
					break;
				}

		}
#ifdef DEBUG_CMJBITSET
		temp.m_bitset =this->m_bitset; 
#endif
		*this = temp;
			
#ifdef DEBUG_CMJBITSET
	
		_ASSERT((*this) == m_bitset);
	
#endif
	}


	void make_full()
	{

		_ASSERT(m_type != BS_FULL);

		CMJBitset<_N> temp;

		temp.m_type = BS_FULL;
		temp.m_len = 0;
		switch (m_type)
		{
		case BS_NORMAL:
				{
				for (_INDEX i = 0; i < _N; i++)
				{
					if (!test(i))
					{
						temp.reset_set_bit(i, false);
					}
				}
				break;
				}
			case BS_SPARSE:
				{
					_INDEX bit= 0;
					_INDEX unset_bit = 0;
					_INDEX i = 0;
					while(i < m_len)
					{
						bit += m_pData[i]; 
						for (_INDEX j = unset_bit; j < bit; j++)
						{
							temp.reset_set_bit(j, false);
						}
						bit++;
						unset_bit = bit;
						i++;

					}
					for (_INDEX j = bit ; j < _N; j++)
					{
						for (_INDEX j = unset_bit; j < bit; j++)
						{
							temp.reset_set_bit(j, false);
						}
					}
					break;
				}

		}
#ifdef DEBUG_CMJBITSET
		temp.m_bitset =this->m_bitset; 
#endif
		*this = temp;
			
#ifdef DEBUG_CMJBITSET
	
		_ASSERT((*this) == m_bitset);
	
#endif
	}



	void make_normal()
	{

		_ASSERT(m_type != BS_NORMAL);
			
#ifdef DEBUG_CMJBITSET
	
		//_ASSERT((*this) == m_bitset);
	
#endif
		CMJBitset<_N> temp;

		temp.m_type = BS_NORMAL;
		temp.allocate_normal(sizeof(std::bitset<_N>));

		switch (m_type)
		{
		case BS_FULL:
				{
				std::bitset<_N> *pL = (std::bitset<_N> *)temp.m_pData;
					_INDEX bit= 0;
					_INDEX i = 0;
					pL->set();

					while(i < m_len)
					{
						bit += m_pData[i]; // unset bit
					
						
						pL->set(bit,false);
						
						bit++;
						i++;

					}
				
					break;
				}
			case BS_SPARSE:
				{
					std::bitset<_N> *pL = (std::bitset<_N> *)temp.m_pData;
					pL->reset();
		
					_INDEX bit= 0;
					_INDEX i = 0;
					while(i < m_len)
					{
						bit += m_pData[i]; 
					
							pL->set(bit);
						bit++;
						i++;
			
					}
				
					break;
				}

		}
#ifdef DEBUG_CMJBITSET
		temp.m_bitset =this->m_bitset; 
		//_ASSERT(temp == temp.m_bitset);
#endif
		*this = temp;
			
#ifdef DEBUG_CMJBITSET
	
		//_ASSERT((*this) == m_bitset);
	
#endif
	}


	friend ostream& operator<<(ostream& _O, const CMJBitset<_N>& _R)	{
		for (size_t _P = _N; 0 < _P; )
		_O << _R.test(--_P) ? '1' : '0';
		return (_O); 
	}
		// TEMPLATE operator>>
	friend istream& operator>>(istream& _I, CMJBitset<_N>& _R)	{
		ios_base::iostate _St = ios_base::goodbit;
		bool _Chg = false;
		string _X;
		const istream::sentry _Ok(_I);
		if (_Ok)
		{
			_TRY_IO_BEGIN
				int _C = _I.rdbuf()->sgetc();
				for (size_t _M = _R.size(); 0 < _M;
				_C = _I.rdbuf()->snextc(), --_M)
				{
					if (_C == EOF)
					{
						_St |= ios_base::eofbit;
						break;
					}
					else if (_C != '0' && _C != '1')
						break;
					else if (_X.max_size() <= _X.size())
					{
						_St |= ios_base::failbit;
						break; 
					}
					else
						_X.append(1, (char)_C), _Chg = true; 
				}
				_CATCH_IO_(_I); 
		}
		if (!_Chg)
			_St |= ios_base::failbit;
		_I.setstate(_St);
		_R = _X;
		return (_I);
	}


private:
	// 1 (01) (1=0) = 00 (11)
	// 01 (101) (01=1) =  000 (111)
	

	void set_unset_bit(_INDEX bit,bool retype=true){
	if (retype)
		{
			switch (m_type)
			{

			case BS_FULL:
				if ( m_len > _N - ((_N/8)/sizeof(_DATA)))
				{
					make_sparse();
				}
				else if(m_len -1  > ((_N/8)/sizeof(_DATA)))
				{
					make_normal();
				}
				break;
			case BS_NORMAL:
				{
					static int check =0;
					check++;
					if (check & CMJBITSET_CHECK_NORMAL_MASK == CMJBITSET_CHECK_NORMAL_MASK)
					{
						std::bitset<_N> *pL = (std::bitset<_N> *)m_pData;
			
						_INDEX count = pL->count();
						if (count - 1 < ((_N/8)/sizeof(_DATA)))
						{
							make_sparse();
						}
						else if (count > _N - ((_N/8)/sizeof(_DATA)))
						{

							make_full();
						}
			

					}


				}
				break;
			case BS_SPARSE:
				{
				if (m_len != _N-1 && m_len > _N - ((_N/8)/sizeof(_DATA)))
				{
					make_full();
				}
				else if(m_len != _N-1 && m_len +1  > ((_N/8)/sizeof(_DATA)))
				{
					make_normal();
				}
				break;	


				}

			}

		}

		switch (m_type)
		{

		case BS_SPARSE:
			{
			_INDEX pos = 0;
			_INDEX prevpos = 0;
			_INDEX i = 0;	

			if (m_len == _N -1)
			{
				m_len = _N;
			}
			else
			{
				while (i < m_len)
				{
					if (bit <= pos + m_pData[i] )
					{
						allocate(m_len +1);
						memmove(&m_pData[i+1], &m_pData[i], (m_len -1 - i) * sizeof(_DATA));
						m_pData[i] = bit - pos ;
						m_pData[i+1] = m_pData[i+1] + pos - bit -1;
						_ASSERT(test(bit));


						return;

					}
					pos += m_pData[i++] +1;
		
				}
	
				allocate(m_len +1);
				m_pData[m_len-1] = bit - pos;
			}
			break;
			}
		case BS_NORMAL:
			((std::bitset<_N> *)m_pData)->set(bit);
			break;

		case BS_FULL:
			{
				if (m_len == 0)
				{
					m_type = BS_SPARSE;
					allocate(1);
					m_pData[0]= bit;
				}
				else
				{
					_INDEX pos = 0;
					_INDEX i = 0;
					do{

						pos += m_pData[i];
			
						if (pos == bit)
						{
							_INDEX offset = m_pData[i];
							m_len--;
							memmove(&m_pData[i],&m_pData[i+1],(m_len -i) * sizeof(_DATA) );
							m_pData[i] += offset+1;
							return;
						}
						_ASSERT(pos < bit);
						pos++;
						i++;
						_ASSERT(i < _N);
					
					}while(1);
				}
			


			break;
			}
		}


		_ASSERT(test(bit));
		
	}


	void reset_normal_type()
	{

		static int check=0;
		if (m_type == BS_NORMAL)
		{
			check++;
			if ((check & CMJBITSET_CHECK_NORMAL_MASK) == CMJBITSET_CHECK_NORMAL_MASK)
			{
					std::bitset<_N> *pL = (std::bitset<_N> *)m_pData;
			
					_INDEX count = pL->count();
					if (count < ((_N/8)/sizeof(_DATA)))
					{
						make_sparse();
					}
					else if (count > _N - ((_N/8)/sizeof(_DATA)))
					{
						make_full();
					}
			}
		}
	}

	// 01 (101) 0 = 2 (001)

	void reset_set_bit(_INDEX bit, bool retype = true){

		if (retype)
		{
			switch (m_type)
			{

			case BS_FULL:
				if (m_len != _N - 1 && m_len > _N - ((_N/8)/sizeof(_DATA)))
				{
					make_sparse();
				}
				else if(m_len != _N - 1 && m_len +1  > ((_N/8)/sizeof(_DATA)))
				{
					make_normal();
				}
				break;
			case BS_NORMAL:
				{
					static int check =0;
					check++;
					if ((check & CMJBITSET_CHECK_NORMAL_MASK) == CMJBITSET_CHECK_NORMAL_MASK)
					{
						std::bitset<_N> *pL = (std::bitset<_N> *)m_pData;
			
						_INDEX count = pL->count();
						if (count - 1 < ((_N/8)/sizeof(_DATA)))
						{
							make_sparse();
						}
						else if (count > _N - ((_N/8)/sizeof(_DATA)))
						{

							make_full();
						}
			

					}


				}
				break;
			case BS_SPARSE:
				{
				if ( m_len > _N - ((_N/8)/sizeof(_DATA)))
				{
					make_full();
				}
				else if(m_len -1  > ((_N/8)/sizeof(_DATA)))
				{
					make_normal();
				}
				break;	


				}

			}

		}

		switch (m_type)
		{
		case BS_SPARSE:
			if (m_len == _N)	
			{
				allocate(_N -1);
				memset((void *)(m_pData ), 0, (_N -1) * sizeof(_DATA));
				m_pData[bit] = 1;
				//_ASSERT(!test(bit));
			}
			else
			{
				_INDEX pos = 0;
				_INDEX i = 0;
				do{
					pos += m_pData[i];
			
					if (pos == bit)
					{
						_INDEX offset = m_pData[i];
						m_len--;
						memmove(&m_pData[i],&m_pData[i+1],(m_len -i) * sizeof(_DATA) );
						m_pData[i] += offset+1;
						return;
					}
					_ASSERT(pos < bit);
					pos++;
					i++;
					_ASSERT(i < _N);

				}while(1);
			}
			break;
		case BS_NORMAL:
			{
				((std::bitset<_N> *)m_pData)->set(bit,0);
				break;

			}
		case BS_FULL:

			{
			_INDEX pos = 0;
			_INDEX prevpos = 0;
			_INDEX i = 0;	

			if (m_len == _N -1)
			{
				m_len = _N;
			}
			else
			{
				while (i < m_len)
				{
					if (bit <= pos + m_pData[i] )
					{
						allocate(m_len +1);
						memmove(&m_pData[i+1], &m_pData[i], (m_len -1 - i) * sizeof(_DATA));
						m_pData[i] = bit - pos ;
						m_pData[i+1] = m_pData[i+1] + pos - bit -1;
						_ASSERT(!test(bit));


						return;

					}
					pos += m_pData[i++] +1;
		
				}
	
				allocate(m_len +1);
				m_pData[m_len-1] = bit - pos;
			}
			break;
			}
		}
		_ASSERT(!test(bit));

	}
#ifdef DEBUG_CMJBITSET
	void check_heap() const
	{
		_ASSERTE(_CrtCheckMemory());
	
		if (m_pData != &m_Default[0])
		{
			_ASSERTE(_CrtIsValidHeapPointer(m_pData));
		}
	}
#endif

	void _Xinv() const
		{/*_THROW(invalid_argument("invalid CMJBitset<N> char"));*/ }
	void _Xoflo() const
		{/*_THROW(overflow_error(
			"CMJBitset<N> conversion overflow"));*/ }
	void _Xran() const
		{/*_THROW(out_of_range("invalid CMJBitset<N> position"));*/ }

};


#ifdef  _MSC_VER
#pragma pack(pop)
#endif  /* _MSC_VER */

#endif // !defined(AFX_MJBITSET_H__44E16525_5D70_4530_B0C1_5E90AAA4F4CA__INCLUDED_)

/*
 * 
 * Copyright (c) 2004 by MarsJupiter LTD.  ALL RIGHTS RESERVED
 * based on bitset
 * Copyright (c) 1994 by P.J. Plauger.  ALL RIGHTS RESERVED. 
 * Consult your license regarding permissions and restrictions.
 */

⌨️ 快捷键说明

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