C#集合之位数组的用法

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

1.BitArray类

BitArray类是一个引用类型,它包含一个int数组,其中每32位使用一个新整数。

示例:

    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类。

    //对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);

输出:

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

输出:

    //也可以把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#集合之位数组的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • C#集合之链表的用法

    LinkedList<T>是一个双向链表,其元素会指向它前面和后面的元素.这样,通过移动到下一个元素可以正向遍历链表,通过移动到前一个元素可以反向遍历链表. 链表在存储元素时,不仅要存储元素的值,还必须存储每个元素的下一个元素和上一个元素的信息.这就是LinkedList<T>包含LinkedListNode<T>类型的元素的原因.使用LinkedListNode<T>,可以获得列表中的下一个和上一个元素.LinkedListNode<T>定义了

  • C#集合之集(set)的用法

    包含不重复元素的集合称为“集(set)”..NET Framework包含两个集HashSet<T>和SortedSet<T>,它们都实现ISet<T>接口.HashSet<T>集包含不重复元素的无序列表,SortedSet<T>集包含不重复元素的有序列表.ISet<T>接口提供的方法可以创建合集,交集,或者给出一个是另一个集的超集或子集的信息. var companyTeams = new HashSet<string>

  • C#集合之不变集合的用法

    如果对象可以改变其状态,就很难在多个同时运行的任务中使用.这些集合必须同步.如果对象不能改变器状态,就很容易在多个线程中使用.Microsoft提供了一个新的集合库:Microsoft Immutable Collection.顾名思义,它包含不变的集合类————创建后不能改变的集合类.该类在System.Collection.Immutable中定义. //使用静态的Create方法创建该数组,Create方法被重载,可以传递任意数量的元素 ImmutableArray<string> a1

  • C#集合之有序列表的用法

    如果需要基于键对所需集合排序,就可以使用SortedList<TKey,TValue>类.这个类按照键给元素排序.这个集合中的值和键都可以使用任何类型.定义为键的自定义类型需要实现IComparer<T>接口,用于给列表中的元素排序.使用构造函数创建一个有序列表,在用Add方法添加: var books = new SortedList<string, string>(); books.Add("Professional WPF Programming&quo

  • C#集合之字典的用法

    字典表示一种复杂的数据结构,这种数据结构允许按照某个键来访问元素.字典也称为映射或散列表.字典的主要特性是能根据键快速查找值.也可以自由添加和删除元素,这有点像List<T>(https://www.jb51.net/article/244084.htm),但没有在内存中移动后续元素的性能开销.下图是一个简化表示,键会转换位一个散列.利用散列创建一个数字,它将索引和值关联起来.然后索引包含一个到值的链接.一个索引项可以关联多个值,索引可以存储为一个树型结构. .NET Framework提供了

  • C#集合之列表的用法

    目录 1.创建列表 2.添加元素 3.插入元素 4.访问元素 5.删除元素 6.搜索 7.排序 8.类型转换 9.只读集合 .NET Framework为动态列表List提供泛型类List<T>.这个类实现了IList,ICollection,IEnumerable,IList<T>,ICollection<T>,IEnumerable<T>接口. 1.创建列表 创建一个赛车手类,下面的例子会用到: public class Racer : ICompara

  • C#集合之栈的用法

    栈(Stack)和队列是非常类似的一个容器,只是栈是一个后进先出(LIFO)的容器.栈用Push()方法在栈中添加元素,用Pop()方法获取最近添加的一个元素: Stack<T>与Queue<T>类(https://www.jb51.net/article/244090.htm)类似,实现了ICollection和IEnumerable<T>接口.Stack<T>类的成员: 在foreach语句中,栈的枚举器不会删除元素,它只会逐个返回元素.使用Pop()方

  • C#集合之可观察集合的用法

    如果需要集合中的元素何时删除或添加的信息,可以使用ObservableCollection<T>类.这个类是为WPF定义的,这样UI就可以得知集合的变化.这个类在程序集WindowsBase中定义,需要引用这个程序集.ObservableCollection<T>类派生自Collection<T>基类,该基类可用于创建自定义集合,并在内部使用List<T>类.重写基类的虚方法SetItem()和RemoveItem(),以触发CollectionChange

  • C#集合之队列的用法

    队列是其元素按照先进先出(FIFO)的方式来处理的集合.队列使用System.Collections.Generic名称空间中的泛型类Queue<T>实现.在内部,Queue<T>类使用T类型的数组,这类似List<T>(https://www.jb51.net/article/244084.htm)类型.队列实现ICollection和IEnumerable<T>接口,但没有实现ICollection<T>接口,所以ICollection<

  • C#集合之位数组的用法

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

  • Java中Map集合中的Entry对象用法

    Entry: 键值对 对象. 在Map类设计是,提供了一个嵌套接口(static修饰的接口):Entry.Entry将键值对的对应关系封装成了对象,即键值对对象,这样我们在遍历Map集合时,就可以从每一个键值对(Entry)对象中获取对应的键与对应的值. Entry为什么是静态的? Entry是Map接口中提供的一个静态内部嵌套接口,修饰为静态可以通过类名调用. Map集合遍历键值对的方式: Set<Map.Entry<K,V>> entrySet(); //返回此映射中包含的映射

  • C语言 array数组的用法详解

    目录 一维数组的创建与初始化 程序一: 程序二: 程序三 程序四(二维数组 - 二维数组 的 列 绝对不能 省略 ) 二维数组在内存中的存储 程序一 数组作为函数参数,怎么作? 实例:冒泡排序 数组名: 一维数组的创建与初始化 数组是一种相同类型元素的集合 程序一: #include<stdio.h> #include<string.h> int main() { 创建一个数组 int arr1[10];// [常量] 初始化 int arr[10]={1,2,3};不完全初始化,

  • Go语言学习之数组的用法详解

    目录 引言 一.数组的定义 1. 语法 2. 示例 二.数组的初始化 1. 未初始化的数组 2. 使用初始化列表 3. 省略数组长度 4. 指定索引值的方式来初始化 5. 访问数组元素 6. 根据数组长度遍历数组 三. 访问数组元素 1. 访问数组元素 2. 根据数组长度遍历数组 四.冒泡排序 五.多维数组 1. 二维数组 2. 初始化二维数组 3. 访问二维数组 六.向函数传递数组 1. 形参设定数组大小 2. 形参未设定数组大小 3. 示例 总结 引言 数组是相同数据类型的一组数据的集合,数

  • C语言详细讲解指针数组的用法

    目录 1. 指针数组定义方法 2. 指针的指针(二级指针) 3. 字符串和指针 4. 数组指针 定义方法 数组指针的用法 1. 指针数组定义方法 格式: 类型说明符 *数组名[ 元素个数 ] int *p[10]; // 定义了一个整型指针数组p,有10个元素,都是int *类型的变量 指针数组的分类: 同指针类型的分类,见上一篇 大多数情况下,指针数组都用来保存多个字符串. #include <stdio.h> int main() { char *name[5] = {"Hell

  • 前端进阶JS数组高级用法大全教程示例

    目录 1.批量制造数据 2.数组合并去重 3.创建数组的几种方式 4.类数组 常见的类数组 判断是否是类数组 类数组如何转换为数组 如何让类数组使用上数组丰富的内建方法 类数组和数组的区别 5.数组方法的使用注意事项 数组的长度 数组的空元素 empty 基于值进行运算,空位的值作为undefined join和toString,空位怎么处理 数组不会自动添加分号 indexOf与includes 数组可变长度问题 数组查找和过滤 改变自身的方法 delete误区 push vs concat

  • Python列表list数组array用法实例解析

    本文以实例形式详细讲述了Python列表list数组array用法.分享给大家供大家参考.具体如下: Python中的列表(list)类似于C#中的可变数组(ArrayList),用于顺序存储结构.   创建列表 复制代码 代码如下: sample_list = ['a',1,('a','b')] Python 列表操作 复制代码 代码如下: sample_list = ['a','b',0,1,3] 得到列表中的某一个值 复制代码 代码如下: value_start = sample_list

  • PHP常见数组函数用法小结

    本文实例讲述了PHP常见数组函数用法.分享给大家供大家参考,具体如下: 1.array array_merge(array $array1 [, array  $array2 [, $array]]) 函数功能:将一个或多个数组的单元合并起来,一个数组中的值附加在前一个数组的后面.返回结果的数组. 如果输入的数组中有相同的字符串键名,则该键名后面的值将覆盖前一个值.然而,如果数组包含数字键名,后面的值将不会覆盖原来的值,而是附加到后面. 如果只给了一个数组并且该数组是数字索引的,则键名会以连续方

  • C#二维数组基本用法实例

    本文实例讲述了C#二维数组基本用法.分享给大家供大家参考,具体如下: //定义数组 string[,] classes = new string[5, 2]; //正确的C#二维数组使用方法 classes[i, 0] = ""; //错误的使用方法 classes[i][0]=""; 据说这种形式的C#二维数组叫做锯齿数组, 一段例子以供参考: // 声明一个锯齿型数组,该数组有两个元素 int[][] myArray = new int[2][]; // 其中第

  • 老生常谈JavaScript数组的用法

    JavaScript数组简介 JavaScript中的数组与其他语言中的数组是不同的,主要体现在: 数组中存储的各项可以是不同类型的数据 数组的大小是动态变化的,当新增项时或移除项时可以动态的改变大小来容纳当前数据项 在JavaScript中创建数组 在JavaScript中创建数组有两种方式: 其一:调用数组的构造函数 var a = new Array(3);//创建一个长度为3的数组 var a = new Array(1,2,3)//创建一个数组内容为1,2,3的数组 另外,通过构造函数

随机推荐