C#集合之位数组

时间:2022-09-03 13:45:51

  如果需要处理的数字有许多位,就可以使用BitArray类和BitVector32结构。BitArray类位于System.Collection,BitVector32结构位于System.Collection.Specialized。
  这两种类型最重要的区别是,BitArray类可以重新设置大小,如果事先不知道需要的位数,就可以使用BitArray类。BitVector32结构是基于栈的,因此比较快。BitVector32结构仅包含32位,它们存储在一个整数中。

1.BitArray类
  BitArray类是一个引用类型,它包含一个int数组,其中每32位使用一个新整数。
   C#集合之位数组

  示例:

    static void BitArrayDemo()
{
var bits1 = new BitArray(8);
bits1.SetAll(
true);
bits1.Set(
1, false);
bits1[
5] = false;
bits1[
7] = false;
Console.Write(
"initialized: ");
DisplayBits(bits1);
Console.WriteLine();
//int i = Convert.ToInt32(bits1);


DisplayBits(bits1);
bits1.Not();
Console.Write(
" not ");
DisplayBits(bits1);
Console.WriteLine();

var bits2 = new BitArray(bits1);
bits2[
0] = true;
bits2[
1] = false;
bits2[
4] = true;
DisplayBits(bits1);
Console.Write(
" or ");
DisplayBits(bits2);
Console.Write(
" : ");
bits1.Or(bits2);
DisplayBits(bits1);
Console.WriteLine();


DisplayBits(bits2);
Console.Write(
" and ");
DisplayBits(bits1);
Console.Write(
" : ");
bits2.And(bits1);
DisplayBits(bits2);
Console.WriteLine();

DisplayBits(bits1);
Console.Write(
" xor ");
DisplayBits(bits2);
bits1.Xor(bits2);
Console.Write(
" : ");
DisplayBits(bits1);
Console.WriteLine();
}

static void DisplayBits(BitArray bits)
{
foreach (bool bit in bits)
{
Console.Write(bit
? 1 : 0);
}
}

 

 

2.BitVector32结构
  如果事先知道需要的位数,就可以使用BitVector32结构代替BitArry类。BitVector32结构效率较高,因为它是一个值类型,在整数栈上存储位。一个整数可以存储32位。如果需要更多的位,可以使用多个BitVector32值或BitArray类。
  C#集合之位数组

    //对CreateMask方法的第一个调用来访问第一位的一个掩码
//调用CreateMask后,bit1被设置为1。再次调用CreateMask方法,把第一个掩码作为参数传递给CreateMask方法,返回来第二位的一个掩码(是2)

var bits1 = new BitVector32();
int bit1 = BitVector32.CreateMask(); //1
int bit2 = BitVector32.CreateMask(bit1); //2
int bit3 = BitVector32.CreateMask(bit2); //4
int bit4 = BitVector32.CreateMask(bit3); //8
int bit5 = BitVector32.CreateMask(bit4); //16

bits1[bit1]
= true;
bits1[bit2]
= false;
bits1[bit3]
= true;
bits1[bit4]
= true;
Console.WriteLine(bits1);

  输出:
  C#集合之位数组

  

//除了用CreateMask方法创建掩码之外,还可以自己定义掩码,也可以一次设置多位。
//十六进制abcdef与二进制1010 1011 1100 1101 1110 1111相同
bits1[0xabcdef] = true;
Console.WriteLine(bits1);

  输出:
  C#集合之位数组

    //也可以把32位分别放在不同的片段中
bits1[0xabcdef] = true;
Console.WriteLine(bits1);


int received = 0x79abcdef;

var bits2 = new BitVector32(received);
Console.WriteLine(bits2);
//创建6个片段。第一个片段需要12位,有16进制0xfff定义。
//第一次调用CreateSection方法直接受0xfff,为最前面的12位分配内存。
//第二次调用CreateSection方法,将第一个片段和偏移量传递
BitVector32.Section sectionA = BitVector32.CreateSection(0xfff);
BitVector32.Section sectionB
= BitVector32.CreateSection(0xff, sectionA);
BitVector32.Section sectionC
= BitVector32.CreateSection(0xf, sectionB);
BitVector32.Section sectionD
= BitVector32.CreateSection(0x7, sectionC);
BitVector32.Section sectionE
= BitVector32.CreateSection(0x7, sectionD);
BitVector32.Section sectionF
= BitVector32.CreateSection(0x3, sectionE);
//bits2[sectionA],把一个BitVector32.Section类型的值传递给BitVector32结构的索引器,会返回一个int。IntToBinaryString方法将这个int表示
Console.WriteLine("Section A: " + IntToBinaryString(bits2[sectionA], true));
Console.WriteLine(
"Section B: " + IntToBinaryString(bits2[sectionB], true));
Console.WriteLine(
"Section C: " + IntToBinaryString(bits2[sectionC], true));
Console.WriteLine(
"Section D: " + IntToBinaryString(bits2[sectionD], true));
Console.WriteLine(
"Section E: " + IntToBinaryString(bits2[sectionE], true));
Console.WriteLine(
"Section F: " + IntToBinaryString(bits2[sectionF], true));


static string IntToBinaryString(int bits, bool removeTrailingZero)
{
var sb = new StringBuilder(32);

for (int i = 0; i < 32; i++)
{
if ((bits & 0x80000000) != 0)
{
sb.Append(
"1");
}
else
{
sb.Append(
"0");
}
bits
= bits << 1;
}
string s = sb.ToString();
if (removeTrailingZero)
return s.TrimStart('0');
else
return s;
}

  输出:
  C#集合之位数组