“集合”的实现及理解

#include <iostream>
#include "RoleManage.h"
using namespace std;
//左移代表乘2 右移代表除2
typedef struct set
{
    int size;//能存储元素规模
    //数组大小应该看类型 如v为 ushort应该一个数可以存16个 大小为arr/16+1||(size+15)
    int arraysize;
    //向量组 每个向量能存储16个
    unsigned short *v;
} Bitset, *Set;

Set InitSet(int size)
{
    Set _set = new Bitset;
    _set->size = size;
    //一个US类型可以表示16个 故数组大小为1+size/16
    //书中这种向右移动4位的运算方式等同于/16
    _set->arraysize = (size+15)>>4;
    //书中v大小为size 个人认为有错,有不同意见的朋友欢迎探讨
    _set->v = new unsigned short[_set->arraysize];
    for (int i = 0; i <_set->arraysize; i++)
    {
        _set->v[i] = 0;
    }
    return _set;
}

//把B赋值给A
void SetAsign(Set A, Set B)
{
    if(A->size != B->size)
        return;
    for (int i = 0; i < A->size; i++)
    {
        A->v [i] = B->v[i];
    }
}

//计算位置大小 除类型的大小 UShort为16 故要/16 按位的话/4即可
int ArrayIndex(int x){
    return x>>4;
}

//计算这个数在一个ushort里面所在的第几个位置 除16取余+1即可
//输入10二进制为1010为15 1111 &计算得1010表示10 之后右移
unsigned short BitMask(int x){
    return 1<<(x&15);//x&15 表达 x%15
}

//位插入运算 查找数组位置  找到x%16放置 用|运算
//如17插入,此时数组v[1]中为00100000,表示第七个位置有东西,
//17%16+1=2 |运算后v[1]为00100010
void SetInsert(int x,Set s){
    if(x<0||s->size<x)
        return;
    s->v[ArrayIndex(x)] |= BitMask(x);
}

//删除元素运算 先取反再去取&
//如删除17,此时数组v[1]中为00100010,
//表示第2、7个位置有东西,17%16+1=2 ~2取反为11111101 &运算后v[1]为00100000
void SetDelete(int x,Set s ){
     if(x<0||s->size<x)
        return;
     s->v[ArrayIndex(x)] &= ~BitMask(x);
}

//检测元素是否存在
int SetMember(int x,Set set){
    if(x<0||x>set->size)
        return 0;
    //首先查找数组对应位置,与x相对的位置
    //如3 此时在数组第一个位置 BitMask值为1000 表示第4数,第1个为0
    return set->v[ArrayIndex(x)] & BitMask(x);
}

int SetEqual(Set A,Set B){
    if(A->size != B->size)
        return 0;
    for (int i = 0; i < A->arraysize; i++)
    {
        if(A->v[i]!= B->v[i])
            return 0;
    }
    return 1;
}

//取并集  如A=1100 B=0110 此时第2、3、4个为并集
Set SetUnion(Set A,Set B){
    Set s=InitSet(A->size);
    for (int i = 0; i < s->arraysize; i++)
    {
        //按位|
        s->v[i] = A->v[i] | B->v[i];
    }
    return s;
}

//取交集  如A=1100 B=0100=>0100 此时第3个为交集
Set SetIntersection(Set A,Set B){
    Set s=InitSet(A->size);
    for (int i = 0; i < s->arraysize; i++)
    {
        //按位&
        s->v[i]=A->v[i] & B->v[i];
    }
    return s;
}

//取差集  如A=111000 B=001000=>取&为001000 再异或110000 此时第5.6个为差集
Set SetDifference(Set A,Set B){
    Set s=InitSet(A->size);
    for (int i = 0; i < s->arraysize; i++)
    {
        //按位& 再^
        s->v[i]=A->v[i]^(A->v[i]&B->v[i]);
    }
    return s;
}

int main()
{
    Set test = InitSet(100);

    return 0;
}

#include <iostream>#include "RoleManage.h"using namespace std;//左移代表乘2 右移代表除2typedef struct set{    int size;//能存储元素规模    //数组大小应该看类型 如v为 ushort应该一个数可以存16个 大小为arr/16+1||(size+15)    int arraysize;    //向量组 每个向量能存储16个    unsigned short *v;} Bitset, *Set;
Set InitSet(int size){    Set _set = new Bitset;    _set->size = size;    //一个US类型可以表示16个 故数组大小为1+size/16    //书中这种向右移动4位的运算方式等同于/16    _set->arraysize = (size+15)>>4;    //书中v大小为size 个人认为有错,有不同意见的朋友欢迎探讨    _set->v = new unsigned short[_set->arraysize];    for (int i = 0; i <_set->arraysize; i++)    {        _set->v[i] = 0;    }    return _set;}
//把B赋值给Avoid SetAsign(Set A, Set B){    if(A->size != B->size)        return;    for (int i = 0; i < A->size; i++)    {        A->v [i] = B->v[i];    }}
//计算位置大小 除类型的大小 UShort为16 故要/16 按位的话/4即可int ArrayIndex(int x){    return x>>4;}
//计算这个数在一个ushort里面所在的第几个位置 除16取余+1即可//输入10二进制为1010为15 1111 &计算得1010表示10 之后右移unsigned short BitMask(int x){    return 1<<(x&15);//x&15 表达 x%15}
//位插入运算 查找数组位置  找到x%16放置 用|运算//如17插入,此时数组v[1]中为00100000,表示第七个位置有东西,//17%16+1=2 |运算后v[1]为00100010void SetInsert(int x,Set s){    if(x<0||s->size<x)        return;    s->v[ArrayIndex(x)] |= BitMask(x);}
//删除元素运算 先取反再去取&//如删除17,此时数组v[1]中为00100010,//表示第2、7个位置有东西,17%16+1=2 ~2取反为11111101 &运算后v[1]为00100000void SetDelete(int x,Set s ){     if(x<0||s->size<x)        return;     s->v[ArrayIndex(x)] &= ~BitMask(x);}
//检测元素是否存在int SetMember(int x,Set set){    if(x<0||x>set->size)        return 0;    //首先查找数组对应位置,与x相对的位置    //如3 此时在数组第一个位置 BitMask值为1000 表示第4数,第1个为0    return set->v[ArrayIndex(x)] & BitMask(x);}
int SetEqual(Set A,Set B){    if(A->size != B->size)        return 0;    for (int i = 0; i < A->arraysize; i++)    {        if(A->v[i]!= B->v[i])            return 0;    }    return 1;}
//取并集  如A=1100 B=0110 此时第2、3、4个为并集Set SetUnion(Set A,Set B){    Set s=InitSet(A->size);    for (int i = 0; i < s->arraysize; i++)    {        //按位|        s->v[i] = A->v[i] | B->v[i];    }    return s;}
//取交集  如A=1100 B=0100=>0100 此时第3个为交集Set SetIntersection(Set A,Set B){    Set s=InitSet(A->size);    for (int i = 0; i < s->arraysize; i++)    {        //按位&        s->v[i]=A->v[i] & B->v[i];    }    return s;}
//取差集  如A=111000 B=001000=>取&为001000 再异或110000 此时第5.6个为差集Set SetDifference(Set A,Set B){    Set s=InitSet(A->size);    for (int i = 0; i < s->arraysize; i++)    {        //按位& 再^        s->v[i]=A->v[i]^(A->v[i]&B->v[i]);    }    return s;}
int main(){    Set test = InitSet(100);
    return 0;}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

让我试试哈

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值