BitVector32
。在处理布尔值列表时,这是最有效的方法。”我本来会使用 List<bool>
或类似的东西。对我来说,BitVector32
似乎是一种处理位时的低级别东西。
所以问题是,当您需要少于32个项的布尔列表时,是否应该使用 BitVector32
,或者只有在处理低级别东西时才使用它?
BitVector32
。在处理布尔值列表时,这是最有效的方法。”我本来会使用 List<bool>
或类似的东西。对我来说,BitVector32
似乎是一种处理位时的低级别东西。
所以问题是,当您需要少于32个项的布尔列表时,是否应该使用 BitVector32
,或者只有在处理低级别东西时才使用它?
BitVector32
甚至没有实现IEnumerable<T>
。BitVector32是c#位操作的封装(或者你可以称之为抽象)。例如,下面两个语句返回相同的结果:
假设有一个包含一些重复数字的整数数组。我们想要找到所有重复项。当然,您可以简单地使用Linq中的GroupBy函数,但让我们假装我们没有Linq。
The first option is brute force approach where each element will be compared against every element in the given array:
foreach(int i in list)
{
foreach(int j in list)
{
if (i == j)
{
// print this or store it in the result list
}
}
}
Since the brute force approach will result in N square running time, which is pretty inefficient, we can think of utilizing HashSet which will provide a constant lookup time or O(1)
HashSet<int> hashSet = new HashSet<int>();
foreach(int i in list)
{
if (hashSet.Contains(i))
{
// print the duplicate or add it to the result list
}
else
{
hashSet.Add(i);
}
}
这种方法将导致线性运行时间或O(n)。然而,它需要额外的内存n * 4字节(假设我们讨论的是32位整数)。
The third approach is similar to using a hashset except it requires less memory by using a boolean array
bool[] masks = new bool[list.Length];
for (int i = 0; i < list.length; i++)
{
if (masks[list[i]])
{
// print or add to the result list
}
else
{
masks[list[i]] = true;
}
}
它使用布尔数组而不是HashSet。它具有相同的运行时间,即O(n),但需要1/4的内存量,因为布尔类型占用1个字节(8位),而整数占用4个字节(32位)。
Finally, we can solve this problem using the BitVector32 class or the native bit shifting operations.
int check = 0;
for (int i=0; i < list.Length; i++)
{
int mask = 1 << list[i];
if (check & mask == mask)
{
// print or add list[i] to the result list
}
else
{
check = check | mask;
}
}
BitVector32[] bitVectorArray = new BitVector32[maxValue / 32];
bitVectorArray[list[i] / 32] = 1 << list[i] % 32;
这样,您就不必受到32位大小限制的限制。只要内存容量允许,您可以无限扩大大掩码的大小。因此,将所有内容组合在一起:
// This code assumes you know the range of the number in the array
BitVector32[] bitVectorArray = new BitVector32[maxValue / 32];
for (int i=0; i < list.Length; i++)
{
int mask = 1 << list[i] % 32;
if (bitVectorArray[(list[i] - 1)/32][i] & mask == mask)
{
// print or add list[i] to the result list
}
else
{
bitVectorArray[(list[i] - 1)/32] = bitVectorArray[list[i] / 32] | mask;
}
}