Data Structure Learning Manual - IntSet Integer Collection

13.3 IntSet collection of integers

13.3.1 ADT(C#)

  1. Encapsulating a class with an interface is equivalent to only opening part of the functions of the class

    eg:

    public interface ISet_my<T>
        {
            uint[] GetCoordinate(T element);
            uint[] Add(T element);  //加入元素element,返回offset
            uint[] Remove(T element);
            //bool IsMember(T element);
            string GetBinString();  //get 二进制流,其实还是string流而不是bitString
            string PrintBinString();  //返回BinString
            string GetIntString();  //返回intString
            string PrintIntString();  
            ISet_my<T> Union(ISet_my<T> ISet_2);  //并集
            ISet_my<T> Intersect(ISet_my<T> ISet_2);  //交集
            ISet_my<T> DiffSet(ISet_my<T> ISet_2);  //差集
            ISet_my<T> Complement();  //补集
        }
    

13.3.2 Core idea

​ The core idea of ​​IntSet (integer set) is to compress the set to store more data, such as:

Use one int32 space to store 32 ints

Compared with using 32 int32 spaces to store 32 ints, the overhead of IntSet is instantly smaller, right?

13.3.2 Implementation Principle

  1. bitMap (bitmap) and GetCoordinate()

    insert image description here

public class IntSet_my : ISet_my <uint>  
    {
    //member
        private readonly uint[] _bitMap;  //_bitMap的比特流表示IntSet存储信息
        public uint _bitSize { get; }  //_bitMap的比特流占多少位二进制
     //contributor
        public IntSet_my(uint bitSize_0)
        {
            _bitSize = bitSize_0;
            _bitMap = new uint[_bitSize / 32 + 1];  //at lease 1 int32 to store IntSet
            for (int i = 0; i < _bitMap.Length; i++)  //initialize IntSet as null
                _bitMap[i] = 0;  
        }

        //get ( index_bitMap, index_bit )
        public uint[] GetCoordinate(uint e)   
        {
            uint[] coordiante = new uint[2];  //二元坐标
            if (e > _bitSize)  //e不在
                throw new ArgumentOutOfRangeException();
            coordiante[0] = e / 32;  // bitMap index
            coordiante[1] = e % 32;  // bit index in bitMap[ coordiante[0] ]
            return coordiante;
        }
  1. Add() and Remove()

insert image description here

//add int to IntSet
        public uint[] Add( uint e )
        {
            uint[] coordi = GetCoordinate( e ); //get coordinate
            _bitMap[coordi[0]] |= (uint)Math.Pow(2, coordi[1]);  //add 
            return coordi;  //return index
        }

        //remove int from IntSet
        public uint[] Remove(uint e)
        {
            uint[] coordi = GetCoordinate(e);  //get coordinate
            _bitMap[coordi[0]] &= (~coordi[1]);  //remove
            return coordi;  //return index
        }
  1. GetBinString() gets a binary string and GetIntString gets an integer string

insert image description here

public string GetBinString()
        {
            string binString = string.Empty;  //null string
            for (int i = 0; i < _bitMap.Length;)  //each _bitMap[]
            {
                //10进制int->2进制int->2进制string, 并在左侧补齐到32位2进制
                binString = Convert.ToString(_bitMap[i++], 2).PadLeft(32, '0') + binString;  //补0方便之后输出!
            }
            return binString;
        }

        public string PrintBinString()
        {
            string result = GetBinString();  //get binString
            Console.WriteLine("\n从右往左, 第0位为表示0的二进制位\n");
            for (int i = result.Length - 1; i >= 0; )  //each _bitMap[]
            {                
                //print binString                
                for(int k = 0; k < 4; k++)  //each 4 bit intervene  " "
                    Console.Write(result[i--]);
                Console.Write(" ");
                
            }
            Console.Write("\n");
            return result;
        }

insert image description here

public string GetIntString()
        {
            string binString = this.GetBinString();
            string intString = string.Empty;
            for (int i = binString.Length - 1, j = 0; i >= 0; j++)  //each _bitMap[]
            {
                //print IntString
                if (binString[i--] == '1')                
                    intString += " " + Convert.ToString(j);              
            }
            return intString;
        }


        public string PrintIntString()
        {
            string result = this.GetIntString();  //get binString  
            Console.Write("\nIntSet中元素升序排列: {0} \n", result);
            return result;
        }
  1. Union(), Intersect(), Differ()
  • The unit for intersection, union, and complement operations is bitMap[]!
    (though fundamentally a bit in a computer)
  • Encapsulate with interface!
		//Intersect
        public IntSet_my Intersect(IntSet_my IntSet_2)
        {
            IntSet_my IntersectSet;
            
            IntersectSet = new IntSet_my(this._bitSize < IntSet_2._bitSize ? 
                this._bitSize : IntSet_2._bitSize);  //交集大小取小的集合大小
            for (int i = 0; i < IntersectSet._bitMap.Length; i++) // IntersectSet[0~IntSet_2.bitSize) = union                 
                IntersectSet._bitMap[i] = this._bitMap[i] & IntSet_2._bitMap[i];  //运算为&, 实质上是int32->二进制&->int32        
            return IntersectSet;
        }

        //Differ
        public IntSet_my Differ(IntSet_my IntSet_2)
        {
            IntSet_my DifferSet = new IntSet_my(_bitSize);
            int differ_Size = _bitMap.Length < IntSet_2._bitMap.Length ? this._bitMap.Length : IntSet_2._bitMap.Length;
            for (int i = 0; i < differ_Size; i++) // DifferSet[0~_bitMap.Length) = Differ                 
                DifferSet._bitMap[i] = _bitMap[i] & (~IntSet_2._bitMap[i]);
            return DifferSet;
        }

        //Complement
        public IntSet_my Complement()
        {
            IntSet_my CompliSet = new IntSet_my(_bitSize);
            for (uint i = 0; i < _bitMap.Length; i++) // CompliSet[0~IntSet_2.bitSize) = Compli                 
                CompliSet._bitMap[i] = ~this._bitMap[i];
            return CompliSet;
        }
//接口
        ISet_my<uint> ISet_my<uint>.Union(ISet_my<uint> ISet_2)
        {
            return Union(ISet_2 as IntSet_my);
        }

        ISet_my<uint> ISet_my<uint>.Intersect(ISet_my<uint> ISet_2)
        {
            return Intersect(ISet_2 as IntSet_my);
        }

        ISet_my<uint> ISet_my<uint>.DiffSet(ISet_my<uint> ISet_2)
        {
            return Differ(ISet_2 as IntSet_my);
        }

        ISet_my<uint> ISet_my<uint>.Complement()
        {
            return Complement();
        }

13.3.3 Problems encountered and lessons learned

  1. The Convert method does not understand

    When converting decimal int to binary int, I have been thinking about converting it into a computer bit, but I don’t know how to achieve it

    for example:

    Convert.ToBase64CharArray( Byte[] inArray, Int32 offsetIn, Int32 length, Char[] outArray, Int32 offsetOut)

    • inArray is the 8-bit unsigned integer array to be converted
    • offsetIn is the starting index of inArray conversion part
    • length is the length of inArray conversion part
    • outArray is the character array to output
    • offsetOut is the starting index of the character array to be output

    ToBase64 only supports int8, and the storage unit of bitMap is int32.

    This seems to be the only way to accumulate...

  2. When designing, the print function and the getValue function should be separated

  3. The intersection, difference, and complement sets are all calculated in units of int32 array elements

  4. string == ‘1’Instead of string == "1" or string == 1 ! ! !

  5. In VS, how to convert int into string

    • You can’t brute force to char, eg: (char) j, so ASCII and Unicode encoding are not compatible, and it will be garbled
    • Only the string converted to Unicode, eg: Conver.ToString(j)

13.3.4 Issues that still need to be resolved

  1. How to use the generic interface???
  2. Unicode, ASCII, Utf-8 encoding difference

Guess you like

Origin blog.csdn.net/weixin_45549370/article/details/110877259