C#将类别存储在值位掩码中
我正在开发一个有一些类别的应用程序。其目的是将类别存储在一个值中。C#将类别存储在值位掩码中,c#,bit-manipulation,bitmask,C#,Bit Manipulation,Bitmask,我正在开发一个有一些类别的应用程序。其目的是将类别存储在一个值中。 首先,我选择将它们存储在int中。 类别:0、1、2、3… 然后我执行位掩码操作以查找选择的类别。 但问题是,我不能存储超过31个类别 有没有办法建立这样的系统?我不想加入无限数量的类别,但可能会超过64个。 目标语言是C#,但任何其他解决方案都可以 非常感谢 考虑使用,这是一个任意长度的位数组。您可以进行交叉(AND)、并集(OR)和互补(NOT) 现在,您可以有32个以上的类别由整数键入: public static cla
首先,我选择将它们存储在int中。
类别:0、1、2、3…
然后我执行位掩码操作以查找选择的类别。
但问题是,我不能存储超过31个类别 有没有办法建立这样的系统?我不想加入无限数量的类别,但可能会超过64个。
目标语言是C#,但任何其他解决方案都可以 非常感谢 考虑使用,这是一个任意长度的位数组。您可以进行交叉(AND)、并集(OR)和互补(NOT) 现在,您可以有32个以上的类别由整数键入:
public static class Categories
{
public const int Category1 = 1;
public const int Category2 = 2;
//...
public const int Category3123 = 3123;
public const int Max = 5000;
}
BitArray myBitset = new BitArray((int)Categories.Max);
myBitSet.Set(Categories.Category1);
myBitSet.Set(Categories.Category4);
我使用int而不是enum来避免使用BitArray时所有必要的int强制转换,但显然可以将它们封装在处理类别的类中。考虑使用,这是一个任意长度的位数组。您可以进行交叉(AND)、并集(OR)和互补(NOT)
现在,您可以有32个以上的类别由整数键入:
public static class Categories
{
public const int Category1 = 1;
public const int Category2 = 2;
//...
public const int Category3123 = 3123;
public const int Max = 5000;
}
BitArray myBitset = new BitArray((int)Categories.Max);
myBitSet.Set(Categories.Category1);
myBitSet.Set(Categories.Category4);
我使用int而不是enum来避免使用BitArray时所有必要的int类型转换,但显然可以将它们封装在处理类别的类中。如果您这样定义类别:
public enum Categories
{
Category1 = 0x0001,
Category2 = 0x0002,
Category3 = 0x0004,
Category4 = 0x0008,
Category5 = 0x000F,
Category6 = 0x0010,
Category7 = 0x0020,
Category8 = 0x0040,
// etc...
}
var myCategories = Categories.Category1 | Categories.Category4;
if(myCategories | Categories.Category1 > 0)
{
// do something for category 1....
}
然后您可以像这样使用它们:
public enum Categories
{
Category1 = 0x0001,
Category2 = 0x0002,
Category3 = 0x0004,
Category4 = 0x0008,
Category5 = 0x000F,
Category6 = 0x0010,
Category7 = 0x0020,
Category8 = 0x0040,
// etc...
}
var myCategories = Categories.Category1 | Categories.Category4;
if(myCategories | Categories.Category1 > 0)
{
// do something for category 1....
}
如果您这样定义类别:
public enum Categories
{
Category1 = 0x0001,
Category2 = 0x0002,
Category3 = 0x0004,
Category4 = 0x0008,
Category5 = 0x000F,
Category6 = 0x0010,
Category7 = 0x0020,
Category8 = 0x0040,
// etc...
}
var myCategories = Categories.Category1 | Categories.Category4;
if(myCategories | Categories.Category1 > 0)
{
// do something for category 1....
}
然后您可以像这样使用它们:
public enum Categories
{
Category1 = 0x0001,
Category2 = 0x0002,
Category3 = 0x0004,
Category4 = 0x0008,
Category5 = 0x000F,
Category6 = 0x0010,
Category7 = 0x0020,
Category8 = 0x0040,
// etc...
}
var myCategories = Categories.Category1 | Categories.Category4;
if(myCategories | Categories.Category1 > 0)
{
// do something for category 1....
}
我不确定我是否正确理解了你的问题,因此这里有两个答案: 如果你想对一个对象进行分类,但它一次只能容纳一个类别,你完全可以选择只将类别编号存储在int中,而不需要位屏蔽
如果您想存储不同的标志/类别/选项,这些标志/类别/选项对于给定对象应all为true或false,那么您应该使用更长的位掩码。一个bool数组是个好主意-不需要执行位运算来获取和设置值,我非常确定编译器会尽最大努力优化空间使用(正如您所知,单个bool变量实际上是一个字节,但我假设如果创建多个bool变量,它们实际上会被填充到尽可能少的空间中。)无论如何,您可以选择自己的实现,使用long,即64位,甚至是BigInteger-无限位数,您只需首先将其设置为1*10^x,其中x是您希望访问的最大位位置的编号。我不确定我是否正确理解了您的问题,因此这里有两个答案: 如果你想对一个对象进行分类,但它一次只能容纳一个类别,你完全可以选择只将类别编号存储在int中,而不需要位屏蔽
如果您想存储不同的标志/类别/选项,这些标志/类别/选项对于给定对象应all为true或false,那么您应该使用更长的位掩码。一个bool数组是个好主意-不需要执行位运算来获取和设置值,我非常确定编译器会尽最大努力优化空间使用(正如您所知,单个bool变量实际上是一个字节,但我假设如果创建多个bool变量,它们实际上会被填充到尽可能少的空间中。)无论如何,您可以选择自己的实现,它是64位的long,甚至是不限位数的BigInteger,您只需首先将其设置为1*10^x,其中x是您希望访问的大位位置的数量。为什么在这里使用位掩码?是否存在对存储效率的首要关注?否则,只需使用类别的
HashSet
从概念上讲,位集和传统的集容器是相同的,位集只是具有特殊性能特征的特定实现。为什么在这里使用位掩码?是否存在对存储效率的首要关注?否则,只需使用类别的
HashSet
从概念上讲,位集和常规集容器是相同的,位集只是具有特殊性能特征的特定实现。如果
int
太小,可以使用byte[]
…如果int
太小,可以使用byte[]
…目的是存储多个类别,所以我认为BitArray很好,就像John说的。其目的是存储多个类别,所以我认为BitArray很好,就像John说的。谢谢你的回答!是否可以在数据库中存储位数组?必须将位提取为字节数组:var array=new byte[(Categories.Max+7)/8];x、 CopyTo(数组,0);然后将字节数组保存到二进制或VARBINARY字段中。谢谢您的回答!是否可以在数据库中存储位数组?必须将位提取为字节数组:var array=new byte[(Categories.Max+7)/8];x、 CopyTo(数组,0);然后将字节数组保存到二进制或VARBINARY字段。