【问题标题】:dividing system.collections.bitarray into sub bitarrays of 32 bits each将 system.collections.bitarray 划分为每个 32 位的子位数组
【发布时间】:2020-08-30 12:21:48
【问题描述】:

我在网上搜索过,但没有得到我需要的东西。 我有一个大小为 15,936 的位数组。我需要将此位数组划分为位数组列表,每个位数组有 32 位(15936/32 = 498 位数组列表)。

无法准确找到如何划分位数组。请帮忙。

谢谢,

【问题讨论】:

  • 你总是可以使用int[498]...

标签: c# .net


【解决方案1】:

您需要的第一个 32 位值使这非常容易,因为您可以将其复制到 int[],然后根据 int 创建一个 BitArray,通过创建单个元素 @987654324 来传递数据@数组:

int[] values = new int[bigBitArray.Length / 32];
bigBitArray.CopyTo(values, 0);
var smallBitArrays = values.Select(v => new BitArray(new[] { v })).ToList();

或者更有效地,为每次迭代重复使用相同的int[]

int[] values = new int[bigBitArray.Length / 32];
bigBitArray.CopyTo(values, 0);
// Reuse this on every iteration, to avoid creating more arrays than we need.
// Somewhat ugly, but more efficient.
int[] buffer = new int[1];
var smallBitArrays = values.Select(v =>
{ 
    buffer[0] = v; 
    return new BitArray(buffer))
}).ToList();

如果这些以与您期望相反的顺序为您提供位数组,只需在调用 CopyTo 之后调用 Array.Reverse(values)

很遗憾BitArray 没有构造函数来获取现有数组、偏移量和计数......这将大大提高效率。 (当然,“切片复制”操作也是如此。)

更通用的选择是为“切片副本”部分精确地创建扩展方法:

public static BitArray CopySlice(this BitArray source, int offset, int length)
{
    // Urgh: no CopyTo which only copies part of the BitArray
    BitArray ret = new BitArray(length);
    for (int i = 0; i < length; i++)
    {
         ret[i] = source[offset + i];
    }
    return ret;
}

然后:

var smallBitArrays = Enumerable
    .Range(0, bigBitArray.Length / 32)
    .Select(offset => bigBitArray.CopySlice(offset * 32, 32))
    .ToList();

【讨论】:

  • 这不起作用,因为带有int 参数的BitArray 构造函数没有初始化BitArray,它设置了它的容量。
  • @Sefe:你看到修复了吗? (不知道为什么这在 修复之后得到了第二次反对,但是嘿......)
  • @Sefe:感谢。啊,好吧-无论如何,现在似乎已经删除了反对票。这个问题让我想起了一个糟糕的 API BitArray :(
  • 这就是我使用 Array.Copy 的原因。即使使用 API,这也是对位数组进行切片的最有效方式(这就是它在底层的工作方式,只是它不需要 CopyTo)。
  • @Sefe:为什么你认为Array.Copynew int[] { v } 更有效率?如果每次迭代都使用相同的字节数组,那会更有效率——我现在将在我的版本中这样做。
【解决方案2】:

您可以将位数组复制到一个字节数组中,将该数组拆分成块并创建新的位数组:

const int subArraySizeBits = 32;
const int subArraySizeBytes = subArraySizeBits / 8;
byte[] bitData = new byte[myBitArray.Length / subArraySizeBytes];
myBitArray.CopyTo(bitData, 0);
List<BitArray> result = new List<BitArray>();
for (int index = 0; index < bitData.Length; index += subArraySizeBytes) {
    byte[] subData = new byte[subArraySizeBytes];
    Array.Copy(bitData, index * subArraySizeBytes, subData, 0, subArraySizeBytes);
    result.Add(new BitArray(subData));
}

【讨论】:

  • 你好,谢谢回复,我也想过这样做。你的答案也很好。
猜你喜欢
  • 1970-01-01
  • 2019-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多