c# 用BitArray来管理包含关系

news/2024/7/6 4:56:39 标签: 数据库

BitArray是.net自带的引用类型,在名称空间Systems.Collections下面。输入BitArray可以看到它的摘要:“管理位值的压缩数组,该值表示为布尔值,其中 true 表示位是打开的 (1),false 表示位是关闭的 (0)”。

定义一个BitArray:

BitArray bitArr = new BitArray(10);
bitArr[3] = true;
bitArr[8] = true;

历遍bitArr的成员,可以看到结果为{false,false,false,true,false,false,false,false,true,false}.

BitArray由于引用类型的本质,可以重新设置大小。在结果数量不定而且总数可能大于32的情况下,比较适合用BitArray来管理包含关系。这里是相对BitVector32来讲的,BitVector32是值类型,而且固定大小32位,它具有数据处理更快的优点。可以根据实际情况来选择。对于这两种类型更多的解释,可以去msdn上查资料。

包含的管理主要包括三个方面:新增,删除,包含判断。

首先自定一个类,含有BitArray的私有字段,同时有Length的属性。

public struct FlagsBitArray
{
    BitArray _array;
    public int Length { get { return _array.Length; } }

    //构造函数
    public FlagsBitArray(int length)
    {
        _array = new BitArray(length);
    }
    //构造函数
    public FlagsBitArray(int[] arr)
    {
        if (arr == null) _array = new BitArray(0);
        else
        {
            var length = arr.Max();
            _array = new BitArray(length);
            AddFlag(arr);
        }
    }
}

可以将新增和删除理解成修改BitArray的相应索引处的bool值,新增改为true,删除改为false。

void ModifyFlag(int[] arr, bool value)
{
    if (arr == null) return;
    var max = arr.Max();
    if (max > _array.Length - 1)//如果提交的数字超出当前索引范围
        _array.Length = max + 1;
    foreach (var x in arr)
    {
        if (x >= 0) _array[x] = value;
        else throw new ArgumentException("负值无效");
    }
}
//加法
public void AddFlag(params int[] newArr) { ModifyFlag(newArr, true); }

//移除
public void RemoveFlag(params int[] newArr) { ModifyFlag(newArr, false); }

判断是否包含更加简单,只需要判断相应索引处的值是否为true。

//判断有没有
public bool HasFlag(int which)
{
    //超出范围,返回false
    if (which < 0 || which > Length - 1) return false;
    return _array[which];
}

 调用代码:

var list = new int[] { 0, 1, 2, 3, 5, 8, 25, 30 };
var arr = new FlagsBitArray(list);
Console.WriteLine("包含25?" + arr.HasFlag(25));
Console.WriteLine("包含20?" + arr.HasFlag(20));
arr.AddFlag(10, 11, 12, 8, 32);
Console.WriteLine(arr.Length);

包含关系的管理,可以用很多方法。List集合、枚举的HasFlag、二进制与运算、BitVector32、BitArray等等。

list集合属于最基本的方法,它可以实现添加删除和包含判断,但是数据的存储和处理时内存的开销较大;

枚举的HasFlag和二进制与运算,以及BitVector32,它们的优点是数据的存储和内存开销较小。但都存在着Int位数限制的问题,枚举和二进制与运算可以通过long和BigInteger来处理,但总体不太灵活。在32位范围内,这三者都是比较有优势的。

BitArray在长度上面比较占优势,可以无限扩充,这样的优势势必会拖累它的运算速度和内存开销,但是,BitArray里面包含了一个Int数组,每32位使用一个新整数。也就是说它占用的空间也是根据所包含的数据长度来调节的,所以整体影响应该不大。

扩充类下面的一些其他函数 

//还原包含的int集合
public List<int> GetIntList()
{
    List<int> res = new List<int>();
    for (int i = 0; i < _array.Length; i++)
        if (_array[i]) res.Add(i);
    return res;
}

//如果Length很大的时候,而且string需要存储到数据库时,可以考虑压缩算法。
public override string ToString()
{
    StringBuilder sb = new StringBuilder(this.Length) { Length = this.Length };
    for (int i = 0; i < this.Length; i++)
        sb[i] = this._array[i] ? '1' : '0';
    return sb.ToString();
}

//FlagsBitArray与String的转换
public static implicit operator string(FlagsBitArray bitArr)
{
    return bitArr.ToString();
}

//String与FlagsBitArray的隐式转换
public static implicit operator FlagsBitArray(string str)
{
    FlagsBitArray res = new FlagsBitArray(str.Length);
    for (int i = 0; i < str.Length; i++)
        res._array[i] = str[i] == '1';
    return res;
}

源代码

转载请注明出处:http://www.cnblogs.com/icyJ/ 


http://www.niftyadmin.cn/n/1849601.html

相关文章

loss下降auc下降_随机梯度下降法介绍及其参数讲解

算法介绍简单来说&#xff0c;梯度下降就是从山顶找一条最短的路走到山脚最低的地方。但是因为选择方向的原因&#xff0c;我们找到的的最低点可能不是真正的最低点。如图所示&#xff0c;黑线标注的路线所指的方向并不是真正的地方。既然是选择一个方向下山&#xff0c;那么这…

JavaScript学习笔记(十六) XMLHttpRequest

1、介绍 &#xff08;1&#xff09;AJAX&#xff08;Asynchronous JavaScript and XML&#xff09; AJAX 原来是指通过异步 JavaScript 从服务器 XML 文档获取数据&#xff0c;然后更新部分网页&#xff0c;避免刷新整个网页 后来&#xff0c;这个词语慢慢成为在浏览器通过脚…

目前在看的书Visual c++ Net 技术内幕第六版

这本书&#xff0c;讲ATL不错。书上以VC2003.net 为环境讲的。

打包自己的的Class文件为Jar文件

java cvf my.jar *.* (不加-)&#xff0c;则把当前的目录里的所有子目录以及文件打包为my.jar&#xff0c;该jar包就在当前目录下 要想用该jar包需要在classpath下现加.;再加上所在jar包的绝对路径\my.jar。 jar -cf my.jar com则把com下的所有文件打包到jar包。 jar -tvf my.j…

JavaScript实战笔记(五) 预览本地图片

一般情况下&#xff0c;实现本地图片预览有两种方法&#xff0c;一种是 DataURL&#xff0c;一种是 BlobURL 所以在开始介绍怎么展示本地图片之前&#xff0c;我们花一点时间了解一下什么是 DataURL 和 BlobURL 1、DataURL &#xff08;1&#xff09;介绍 DataURL 就是以 d…

python中非法变量名_Python变量命名规则(超级详细)

Python 需要使用标识符给变量命名&#xff0c;其实标识符就是用于给程序中变量、类、方法命名的符号&#xff08;简单来说&#xff0c;标识符就是合法的名字&#xff09;。 Python 语言的标识符必须以字母、下画线&#xff08;_&#xff09;开头&#xff0c;后面可以跟任意数目…

最近,看了一个新片子,很不错。介绍给大家。

中文名称&#xff1a;越狱 第一季英文名称&#xff1a;Prison Break Season1资源类型&#xff1a;RMVB版本&#xff1a;[风软FRM字幕组出品]更新第18集泄露版(缺17)发行时间&#xff1a;2005年08月29日导演&#xff1a;Brett Ratner演员&#xff1a;Wentworth Miller .... Mich…

这几天闲着没事情。搞搞xml

先确定一下编译器。看看业务相关的资料。我书签写成写称XML的。还有什么&#xff1f;想起来再加吧&#xff01;