位数组

如果需要处理很多位,就可以使用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("bits1和bits2数组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)操作:0变1,1变0

BitVector32的位操作

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

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

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

//初始化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("最初值:     \t{0}",bits.ToString());

//设置倒数第三位为1

bits[myBit3] = true;

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

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

bits[myBit4 + myBit5] = true;

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

bits[myBit1 | myBit2] = true;

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

使用BitVector32.Section来存储小整数

BitVector32的最后一项功能就是存储小整数,这种情况不常见,可能会用在存储空间极低的设备上.打个比方就是:比如你有三个数,一个在0-10之内,剩下的两个在0-300之内.其实一般情况下,我们用3个int存就可以.如果为了节省空间的话,用一个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();

}

}

}

C#编程(五十七)----------位数组的更多相关文章

  1. C#高级编程五十七天----位数组

    位数组 假设须要处理非常多位,就能够使用BitArray类和BitVector32.BitArray位于命名空间System.Collections中. BitVector32位于命名空间System ...

  2. C和指针 第五章 位数组

    5.4的习题:编写一组函数,实现维数组,函数原型如下: //指定位设置为1void set_bit(char bit_array[], unsigned bit_number); //指定位清零 vo ...

  3. Linux网络编程(五)

    /*Linux网络编程(五)——多路IO复用之select() 网络编程中,使用IO复用的典型场合: 1.当客户处理多个描述字时(交互式输入以及网络接口),必须使用IO复用. 2.一个客户同时处理多个 ...

  4. JavaScript高级编程——引用类型、Array数组使用、栈方法

    JavaScript高级编程——引用类型.Array数组使用.栈方法 <!DOCTYPE html> <html xmlns="http://www.w3.org/1999 ...

  5. 孤荷凌寒自学python第五十七天初次尝试使用python来连接远端MongoDb数据库

    孤荷凌寒自学python第五十七天初次尝试使用python来连接远端MongoDb数据库 (完整学习过程屏幕记录视频地址在文末) 今天是学习mongoDB数据库的第三天.感觉这个东西学习起来还是那么困 ...

  6. 剑指Offer(三十五):数组中的逆序对

    剑指Offer(三十五):数组中的逆序对 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.net/bai ...

  7. 用C语言关于学生管理系统的几种实现方法(一位数组,二维数组,指针,结构体)

    一位数组: #include <stdio.h> #include<string.h> #define N 5 void luru(float s[],int n); void ...

  8. 【五】PHP数组操作函数

    1.输出数组的结构:bool print_r(数组); $arr=array('jack','mike','tom'); print_r($arr);//Array ( [0] => jack ...

  9. C++ 出现bug :二位数组的操作运算,求非对角线的元素的和

    编写一个通用程序,求出二位数组(行数和列数必须相等)的非对角线的元素之和,试建立类MATRIX完成上述功能 #include<iostream> using namespace std; ...

随机推荐

  1. Qt 程序等待多长时间执行Sleep

    #include <QTime> void MainWindow::Sleep(unsigned int msec) { QTime reachTime=QTime::currentTim ...

  2. 开源整理:Android App新手指引开源控件

    开源整理:Android App新手指引开源控件 一个App第一次与用户接触或者发生大版本更新时,常常会用户进行新手引导,而一个好的新手指引,往往能够方便新用户快速了解操作你的应用功能.新手指引的重要 ...

  3. Java基础89 MySQL存储过程

    1.MySQL存储过程   1.1.什么是存储过程 带有逻辑的sql语句:带有流程控制语句(if  while)等等 的sql语句   1.2.存储过程的特点 1)执行效率非常快,存储过程是数据库的服 ...

  4. 测试开发之Django——No1.介绍以及引申

    前言 > 测试行业发展飞速,自动化测试兴起,由此对测试人员的要求与日俱增.随时而来的,就是职能的增加. > 首先需要学习的,就是自动化测试.而由自动化测试引申而来的,就是另外几个新增的岗位 ...

  5. java Stack(栈)

    "Stack" 通常时指"后进后出"(LIFO)的容器,有时栈也被称为叠加栈,因为最后"压入"栈的元素,第一个"弹出"栈 ...

  6. kafka查看消费数据

    一.如何查看 在老版本中,使用kafka-run-class.sh 脚本进行查看.但是对于最新版本,kafka-run-class.sh 已经不能使用,必须使用另外一个脚本才行,它就是kafka-co ...

  7. **PHP二维数组遍历时同时赋值

    php 二维数组遍历赋值 我个人在项目中的写法: //遍历二维数组foreach($tmp_array as $key => $value){ //动态生成图片的URL $attach_url ...

  8. Java编程的逻辑 (16) - 继承的细节

    ​本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http: ...

  9. Kotlin中var和val的区别

    Kotlin中有两个关键字定义变量,这两个关键字外形看着差别很小就只差了一个字母,但实际差别很大的. var是一个可变变量,这是一个可以通过重新分配来更改为另一个值的变量.这种声明变量的方式和Java ...

  10. 翻译 – 从心理学角度看UX设计

    本文是一篇非常不错的关于用户体验设计的文章,本文作者是一个心理学家,他从他所研究的领域去看到用户行为,用户体验,相信会给你带来不一样的观念与知识.翻译水平有限,若有不准确之处欢迎指正. ——————— ...