• 用位向量实现集合抽象数据类型


    #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

  • 相关阅读:
    floating IP 原理分析
    创建 floating IP
    Why Namespace?
    虚拟 ​router 原理分析- 每天5分钟玩转 OpenStack(101)
    链接脚本使用一例2---将二进制文件 如图片、MP3音乐、词典一类的东西作为目标文件中的一个段
    linux-2.6.26内核中ARM中断实现详解(转)
    有关Cache –(1) linux list之中的Prefetc
    Linux 内核中的 GCC 特性
    对entry-common.S和call.S的部分理解1
    kernel&uboot学习笔记
  • 原文地址:https://www.cnblogs.com/kex1n/p/2286589.html
Copyright © 2020-2023  润新知