#include<assert.h>
#include<iostream>
using namespace std;
const int DefaultSize = 100;
class Set
{
public:
Set(int MaxSize = DefaultSize); //构造函数
~Set() {delete []bitVector;} //析构函数
void MakeEmpty() //置空集合
{
for(int i=0; i<MaxSize; i++)
{
bitVector[i] = 0;
}
}
bool AddMember(const int x); //加入新成员x
bool DelMember(const int x); //删除老成员x
Set& operator = (Set& right); //集合right赋值给集合this
Set& operator + (Set& right); //集合right与集合this的并
Set& operator - (Set& right); //集合right与集合this的差
Set& operator * (Set& right); //集合right与集合this的交
bool operator== (Set& right); //判断集合this是否与集合right相等
bool Contains(const int x); //判断x是否是集合this的成员
bool SubSet(Set& right); //判断集合this是否是集合right的子集
private:
int *bitVector; //存储集合元素与的位向量
int MaxSize; //向量的大小
};
Set::Set(int MaxSetSize):MaxSize(MaxSetSize)
{
assert(MaxSize > 0); //检查参数合理性
bitVector = new int[MaxSize]; //分配一个整形数组给位向量
assert(bitVector != 0); //检查存储分配是否成功
MakeEmpty(); //初始化为空集合
}
// 把x加入到集合this中,也就是把位向量的第x个位置为1(x的范围必须是0与MaxSize之间)
// 如果第x个位已经为1,返回false,否则返回true
bool Set::AddMember(const int x)
{
assert(x >= 0 && x < MaxSize); //检查x合理性
if(!bitVector[x])
{
bitVector[x] = 1;
return true;
}
return false;
}
bool Set::DelMember(const int x)
{
//把x从集合this中删除
assert(x >= 0 &&x <= MaxSize); //判断元素x的合理性
if(bitVector[x])
{
bitVector = 0;
return true;
}
return false;
}
Set& Set::operator = (Set& right)
{
//集合right赋值给集合this
assert(MaxSize == right.MaxSize); //判断两个集合是否大小相等
for(int i = 0;i < MaxSize;i++)
{
bitVector[i] = right.bitVector[i];
}
return *this;
}
Set& Set::operator + (Set& right)
{
//集合right与集合this的并
assert(MaxSize == right.MaxSize); //判断两个集合是否大小相等
for(int i = 0;i < MaxSize;i++)
{
bitVector[i] = bitVector[i] || right.bitVector[i]; //按位求“或”
}
return *this;
}
Set& Set::operator - (Set& right)
{
//集合right与集合this的差
assert(MaxSize == right.MaxSize); //判断两个集合是否大小相等
for(int i = 0;i < MaxSize;i++)
{
bitVector[i] = bitVector[i] && !right.bitVector[i]; //按位求“异或”
}
return *this;
}
Set& Set::operator * (Set& right)
{
//集合right与集合this的交
assert(MaxSize == right.MaxSize); //判断两个集合是否大小相等
for(int i = 0;i < MaxSize;i++)
bitVector[i] = bitVector[i] && right.bitVector[i]; //按位求“与”
return *this;
}
bool Set::operator== (Set& right)
{
//判断集合this是否与集合right相等
assert(MaxSize == right.MaxSize); //判断两个集合是否大小相等
for(int i = 0; i < MaxSize; i++)
if(bitVector[i] != right.bitVector[i])
return false;
return true;
}
bool Set::Contains(const int x)
{
//判断x是否是集合this的成员
assert(x >= 0 && x < MaxSize); //检查x合理性
return bitVector[x] != 0;
}
bool Set::SubSet(Set& right)
{
//判断集合this是否是集合right的子集
assert(MaxSize == right.MaxSize); //判断两个集合是否大小相等
for(int i = 0;i < MaxSize;i++)
{
if(bitVector[i] && !right.bitVector[i])
return false;
}
return true;
}
int main()
{
Set a(10),b(10);
a.AddMember(4);
b.AddMember(4);
if(a == b)cout << "a = b" << endl;
else cout << "a != b" << endl;
getchar();
return 0;
}
位运算相关:
位操作符可以处理某个数的个别的位,只针对位,思想和那些&&,||一样
&(与操作)
|(或操作)
^(异或操作)
~(非操作,也叫补运算符,就是取反)
除了~,其他的都可以和"="一起用,例如&=,
移位操作符
<<将左值按位向左移动,>>将左值按位向右移动
记住下面的式子就行了
A<<X,[向左移动X个位] 可看作 A=A*(2^X) A乘以2的X 次方
A>>X,[向右移动X个位] 可看作 A=A/(2^X) A除以2的X 次方
位向量应该是指<bitset>,<vector> 英文原意虽为“向量”,但在标准库中一般称为动态数组。
这里的“位”是指数据位,不是数字位。
在C/C++里,char是8位(1字节),short是16位(2字节),int、long和float是
32位(4字节),double是64位(8字节),long double是80位(10字节)。
举例来说,2是二进制10,2位;4是二进制100,3位;65535是二进制1111 1111 1111 1111,
16位。无符号整型最高可到4,294,967,295,变成二进制正好是32位。
1<<27(1左移27位) = 1乘以(2的27次方)= 134 217 728
quiz1 |= 1 << 27 → quizl = quizl | ( 1
<< 27 ) → quizl = 0 | 134 217 728 =
134 217 728