码迷,mamicode.com
首页 > 编程语言 > 详细

C++中setbit的实现(没有使用引用技术)

时间:2015-04-07 15:40:31      阅读:285      评论:0      收藏:0      [点我收藏+]

标签:

#include <iostream>
#include <string.h>
#define CHAR_BIT 8
using namespace std;

template<size_t _N>
class bitset
{
	typedef unsigned long _Ty; 
	friend ostream & operator << (ostream &_O,const bitset<_N> &_R)
	{
		for(size_t _P=_N;_P>0;)
			_O<<(_R.test(--_P)?'1':'0');//输出
		return _O;
	}
	public:
	bitset()//构造
	{
		_Tidy();//清零
	}
	bitset(const string &_S)//用字符串构造
	{	
	 	_Tidy();
		int _I=0;
		while(_S[_I]!='\0')
		{
			int _D = _S[_I]=='1'?1:0;
			_I++;
			set(_I,_D);
		}
	}
	bitset(int x)//相应位置置1
	{
		_Tidy();
		_A[0]|=(_Ty)x;
	}
	bitset(const string &_S,int _X)//字符串相应位置置1
	{
		_Tidy();
		int _I=0;
		while(_S[_I]!='\0')
		{
			int _D = _S[_I]=='1'?1:0;
			_I++;
			set(_I,_D);
		}
		set(_X,1);
	}
  bitset<_N>& set()//置1
	{
				_Tidy(~(_Ty)0);
				return *this;
	}
	bitset<_N>& set(size_t _P, bool _X = true)//相应位置置1
	{
		if(_X)
	 _A[_P/_Nb] |= ((_Ty)0x1<<(_P%(_N+1))-1);		
		else
		{	
			_A[_P/_Nb] &= ~((_Ty)0x1<<(_P%(_N+1))-1);
		}
	return *this;
	}
	bitset<_N>& reset()//所有位置0
	{
			_Tidy();
			return *this;
	}
	bitset<_N>& reset(size_t _P)//相应位置置0
	{	
		set(_P,0);
		return *this;
	}
	bitset<_N>& flip()//按位取反。
	{
		for(int _I=0;_I<=_Nw;_I++)
		{
			_A[_I]^=(~(_Ty)0x0);
		}
		_Trim();		
	}
	bitset<_N>& flip(size_t _P)//相应位置取反
	{
		_A[_P/_Nb] ^= ((_Ty)0x1<<(_P%(_Nb+1)-1));
		return *this;
	}
	size_t size()const//求位数
	{
		return _N;
	}
	size_t count()const//求1的个数
	{
	 size_t _V=0;
		for(int _I=_Nw;_I>=0;--_I)
			for(_Ty _X=_A[_I];_X!=0;_X>>=4)
			_V+="\0\1\1\2\1\2\2\3\1\2\2\3\2\3\3\4"[0xff&_X];
		return _V;
	}
	bitset<_N> operator~()
	{
		for(int _I=0;_I<=_Nw;++_I)
			_A[_I]=~_A[_I];
		_Trim();
		return *this;
	}
	unsigned long to_ulong() const//转换为long型
	{
		enum{_Assertion=1/(sizeof(unsigned long)%sizeof(_Ty)==0)};
		int _I = _Nw;
		for(;sizeof(unsigned long)/sizeof(_Ty)<=_I;--_I)
				if(_A[_I]!=0)
					break;
		unsigned long _V=_A[_I];
		for(;0<=--_I;)
			_V=_V<<_Nb|_A[_I];
		return (_V);
	}
	string to_string()const//转化为string类型
	{
		string _S;
		for(int _I=0;_I<=_Nw;_I++)
		{	
			for(int _X=_A[_I];_X!=0;)
				{
				_S+=((_X&((_Ty)0x1))==1?"1":"0");
				_X>>=1;
				}
		}
		return _S;
	}
	bool any()const//位域中出现一个1就返回真
	{
		for(int _I=0;_I<=_Nw;++_I)
			if(_A[_I]!=0)
				return true;
		else	return false;	
	}
	bool none()const//位域中没有一个1就返回真
	{
		return !any();
	}
	bitset<_N>& operator&=(const bitset<_N> &_R)//重载&=
	{
			for(int _I=0;_I<=_Nw;_I++)
					_A[_I]&=_R._A[_I];
			return *this;
	}
	bitset<_N>& operator|=(const bitset<_N> &_R)//重载|=
	{
			for(int _I=0;_I<=_Nw;_I++)
					_A[_I]|=_R._A[_I];
			return *this;
	}
	bitset<_N>& operator^=(const bitset<_N> &_R)//重载^=
	{
			for(int _I=0;_I<=_Nw;_I++)
				_A[_I]^=_R._A[_I];
			return *this;
	}
	friend bitset<_N> operator&(const bitset<_N> &_L, const bitset<_N> &_R)
	{
		return (bitset<_N>(_L)&=_R);
	}
	friend bitset<_N> operator|(const bitset<_N> &_L, const bitset<_N> &_R)
	{
		return (bitset<_N>(_L)|=_R);
	}
	friend bitset<_N> operator^(const bitset<_N> &_L, const bitset<_N> &_R)
	{
		return (bitset<_N>(_L)^=_R);
	}
	bitset<_N>& operator<<=(size_t _P)//左移
	{
	int _D = _P/_Nb;
	if(_D!=0)
	{
	int _I;
		for( _I=_Nw;_I>0;_I--)	
			  {
				_A[_I] = _D<=_I?_A[_I-_D]:0;
				}
			for(int _J=0;_J<_D-1;_J++)
				_A[_J] = 0;
	}
	if(_P%_Nb!=0)
	{
		int _I = _Nw;
		for(;_I>0;--_I)
		{
			_A[_I]=(_A[_I]<<(_P%_Nb))|(_A[_I-1]>>(_Nb-_P%_Nb));
		}
	}
		_A[0]<<=(_P%_Nb);
		_Trim();
		return *this;
	}
	bitset<_N>& operator>>=(size_t _P)//右移
	{
		int _D = _P/_Nb;
		if(_D!=0)
		{
			int _I;
			for(_I=0;_I<=_Nw;_I++)
			{
				_A[_I] = _I+_D<=_Nw?_A[_I+_D]:0;
			}
			for(int _J=0;_J<_D;_J++)
				_A[_Nw-_J]=0;
		}
		if(_P%_Nb!=0)
		{	
			int _I = 0;
			for(;_I<_Nw;++_I)
			{	
				_A[_I]=(_A[_I]>>(_P%_Nb))|(_A[_I+1]<<(_Nb-_P%_Nb));
			}
		}
		_A[_Nw]>>=(_P%_Nb);
		_Trim();
		return *this;
	}
	friend bitset<_N> operator<<(const bitset<_N> &_L, size_t _P)
	{
		return bitset<_N>(_L)<<=_P;
	}
	friend bitset<_N> operator>>(const bitset<_N> &_L,size_t _P)
	{
		return bitset<_N>(_L)>>=_P;
	}
	private:
	bool test(size_t _P)const
	{
		return (((_A[_P/_Nb]) & (0x1<<(_P%_Nb)))!=0);
	}
	void _Tidy(_Ty _X=0)
	{
		for(int _I=_Nw;_I>=0;--_I)
			_A[_I]=_X;
		 if(_X!=0)
				_Trim();
	}	
	void _Trim()
	{
		if(_N%_Nb!=0)
	 	    _A[_Nw]&=(((_Ty)0x1<<_N%_Nb)-1);
	}
	enum
	{
		_Nb=CHAR_BIT*sizeof(_Ty),
		_Nw = _N==0?0:(_N-1)/_Nb,
	};
	_Ty _A[_Nw+1];
};
int main()
{	
	bitset<10> bt1(15);
	cout<<bt1<<endl;
	bt1.flip();
	cout<<bt1<<endl;
	return 0;
}
<<=与<<不一样,<<不能改变原来的值,所以在这里需要拷贝,避免在原来的参数上进行修改。

C++中setbit的实现(没有使用引用技术)

标签:

原文地址:http://blog.csdn.net/liuhuiyan_2014/article/details/44919985

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!