• C#编程(五十七)----------位数组


    位数组

    如果需要处理很多位,就可以使用BitArray类和BitVector32.BitArray位于命名空间System.Collections.

    BitVector32位于命名空间System.Collections.Speciallized.

    BitArray

    BitArray是一个引用引用类型,包含一个int数组,32位使用一个新整数.bool类型的数组bool[]差不多

    案例:

    using System;

    using System.Collections;

    using System.Collections.Generic;

    using System.Linq;

    using System.Text;

    using System.Threading.Tasks;

    namespace 可观察的集合

    {

        class Program

        {

            static void Main(string[] args)

            {

                Stack st = new Stack();

                st.Push('A');

                st.Push('B');

                st.Push('C');

                BitArray bits1 = new BitArray(8);//一个有8位的数组

                Console.WriteLine("显示数组中所有位的默认值:");

                Display(bits1);

                Console.WriteLine();

                bits1.SetAll(true);//SetAll()方法将所有的位都置为1

                bits1.Set(1, false);

                bits1[5] = false;

                bits1[7] = false;

                Console.WriteLine("显示数组中所有位的值: ");

                Display(bits1);

                Console.WriteLine();

                Console.WriteLine("倒转数组中所有位的值: ");

                bits1.Not();//Not()方法的结果是所有的位全部翻转过来.如果某位是true,执行Not()方法的结果就是False

                Display(bits1);

                Console.ReadKey();

            }

            public static void Display(BitArray bits)

            {

                foreach (bool item in bits)

                {

                    Console.WriteLine(item ?1 :0);

                }

            }

        }

    }

    BitArray的其他方法:And(),Or().Xor(),Get()演示:

                //BitArray的其他方法演示

                Console.WriteLine();

                BitArray bits2 = new BitArray(bits1);

                bits2.Set(0, true);

                bits2[1] = false;//效果同Set()方法

                bits2[4] = false;

                Console.WriteLine("bits2数组中所有位的值: ");

                Display(bits2);

                Console.WriteLine();

                Console.WriteLine("bits1bits2数组Or的值: ");

                bits1.Or(bits2);

                /*

                 * 使用And(),Or()Xor()方法,可以合并两个BitArray对象

                 * And()方法执行二元AND,只用两个输入数组的位都设置为1,结果位才是1

                 * Or()方法执行二元OR,只要有一个输入数组的位设置为1,结果位就是1.

                 * Xor()方法是异或操作,只有一个输入数组的位设置为1,结果位才是1

                 */

                Display(bits1);

                Console.WriteLine();

                Console.WriteLine("bits1数组Get数字2的值");

                Console.WriteLine(bits1.Get(2));

                Console.ReadKey();

    BitVector32结构

    相比与BitArray,它的有点事速度快,占用空间小,并可以存储小数字.它内部用一个32位的整数来存储数据,因此只能存储32位的比特数据.

    先来看一下简单的未操作,常见的位操作无非就是AND,OR,NOT.

    案例:比如一个8位的数据:0000 1111

    我们想把第二个0设置为1,那么把它和0100 0000进行或操作,就得到结果:0100 1111

    还是上面的那个数:0000 1111,我们想把 最后一个1设置为0,那么把它和1111 1110这个数进行与操作,疾苦得到了结果:0000 1110

    总结:想要操作一个位,我们把其他位都设置成0,把这个位设置成1,这个数就是所谓的位掩码(也成位屏蔽,MSDN里用的是为屏蔽)

    那么如果想要打开一个位(就是把这个位设置成1):

    源数据=源数据OR位掩码

    想要关掉一个位:

    源数据=源数据AND位掩码取反

    解释:位掩码取反就是非(NOT)操作:01,10

    BitVector32的位操作

    了解了基本的位操作BitVector32的理解就会简单多了.

    首先BitVector32本质上用一个32位的数来表示数据,那么初始化BitVector32结构时必须指定一个最初指.用户可以传入一个int或者另一个已经存在的BitVector32来构造一个新的BitVector32.

    BitVector32Data属性返回一个int用来表示内部数据,如果用来显示BitVEctor32的内容,这个Data是没有意义的,因为它是十进制化的结果,这时候用BitVector32ToString()方就可以返回有用的文字说明,案例:

                //初始化BitVector32,设置低4位为1 0x 00 00 00 00 00 00 00 0F

                BitVector32 bits = new BitVector32(0xF);

                //(十六进制)0xF等于(二进制)1111等于(十进制)15

                Console.WriteLine(bits.Data);

                Console.WriteLine(bits.ToString());

    接下来就是最重要的位操作了.

    BitVector32结构体提供索引器(Indexer)可以直接通过bool对象操作BitVector32结构,索引器参数是int,这个int可不睡第几位的意思(BitArray中的索引器是第几位的意思),而是需要一个位掩码(位屏蔽),BitVector32通过这个位掩码来操作内部比特位.

    所以,BitVector32索引器操作其实就是定义好位掩码,接着取回信息或者赋值就可以了.

    案例:

            static void Main(string[] args)

            {

                int mask1 = 1;

                //掩码代表最后一位,二进制表示:0...0001

                int mask2 = 4;

                //掩码代表倒数第三位,二进制表示:0...0000100

                BitVector32 bits = new BitVector32(-1);

                //-1补码:1.1111

                //设置BitVector32全部为1

                Console.WriteLine(bits);

                Console.WriteLine("设置最后一位和倒数第三位为0");

                bits[mask1] = bits[mask2] = false;

                Console.WriteLine(bits);

                Console.WriteLine("设置倒数第三位为1");

                bits[mask2] = true;

                Console.WriteLine(bits);

                Console.ReadKey();

            }

    CreateMask方法

    BitVector32还有一个CreateMask方法,他的作用就是方便用户定义位掩码.

    CreateMask(无参数):返回第一个位(最低位)的位掩码,那么就是0.00001,十进制的话就是1.

    CreateMask(int): 首先判断已知位掩码的合法性,并返回向左移1位的结果.

    案例:

                //初始化BitVector32,全部为0

                BitVector32 bits = new BitVector32(0);

                //创建最低位的掩码,然后陆续常见倒数第二位,倒数第三位...倒数第五位的掩码

                int myBit1 = BitVector32.CreateMask();

                int myBit2 = BitVector32.CreateMask(myBit1);

                int myBit3 = BitVector32.CreateMask(myBit2);

                int myBit4 = BitVector32.CreateMask(myBit3);

                int myBit5 = BitVector32.CreateMask(myBit4);

                Console.WriteLine("最初值:     {0}",bits.ToString());

                //设置倒数第三位为1

                bits[myBit3] = true;

                Console.WriteLine("myBit3 = true    {0}",bits.ToString());

                //将掩码加起来,同时设置两个位

                bits[myBit4 + myBit5] = true;

                Console.WriteLine("myBit4 + myBit5 = true {0}",bits.ToString());

                bits[myBit1 | myBit2] = true;

                Console.WriteLine("myBit1 | myBit2 {0}",bits.ToString());

    使用BitVector32.Section来存储小整数

    BitVector32的最后一项功能就是存储小整数,这种情况不常见,可能会用在存储空间极低的设备上.打个比方就是:比如你有三个数,一个在0-10之内,剩下的两个在0-300之内.其实一般情况下,我们用3int存就可以.如果为了节省空间的话,用一个byte,两个short.如果还想省空间的话,用一个int存就可以,那么这个时候,就需要BitVector32.

    使用BitVector32的静态方法CreateDection返回一个BirVector32.Section结构体.CreateSection需要一个int来制定所村区域的最大整数值(注意只能存0-这个最大值),BitVector32会根据这个最大值来分配所占位长度.接着后续CreateSection函数的调用必须掺入之前的Section,因为Section的创建是建立在前面Section没有占用的空闲位.

    同时,BitVector32 还拥有另一个重载的索引器专门针对Section来进行操作.

    案例:

    using System;

    using System.Collections.Generic;

    using System.Collections.Specialized;

    using System.Linq;

    using System.Text;

    using System.Threading.Tasks;

    namespace 位数组

    {

        class Program

        {

            static void Main(string[] args)

            {

            

                //初始化BitVector32,全部为0

                BitVector32 bits = new BitVector32(0);

               

                //创建Section

                BitVector32.Section sec1 = BitVector32.CreateSection(10);

                BitVector32.Section sec2 = BitVector32.CreateSection(300,sec1);

                BitVector32.Section sec3 = BitVector32.CreateSection(300,sec2);

                //设置每一个Section,注意值要在定义范围之内

                bits[sec1] = 9;

                bits[sec2] = 123;

                bits[sec3] = 289;

                Console.WriteLine("Section 1: {0}",bits[sec1]);

                Console.WriteLine("Section 2: {0}",bits[sec2]);

                Console.WriteLine("Section 3: {0}",bits[sec3]);

                //来看看32位的空间用的怎么样

                Console.WriteLine(bits);

                Console.ReadKey();

            }

        }

    }

  • 相关阅读:
    【洛谷 P4721】【模板】—分治FFT(CDQ分治+NTT)
    【Comet OJ】模拟赛测试 Day2题解
    【Comet OJ】模拟赛测试 Day2题解
    将本地文件夹push到github仓库
    2017-3-7
    彻底理解https!
    2017-3-2 智慧吉首调研工作
    java再巩固
    2017-3-1
    不错的博客哦
  • 原文地址:https://www.cnblogs.com/FinleyJiang/p/7602728.html
Copyright © 2020-2023  润新知