将system.collections.bitarray分成每个32位的子位阵列

时间:2016-12-08 09:17:56

标签: c# .net

我在网上搜索过但没有得到我需要的内容。 我有一个大小为15,936的bitarray。我需要将这个位数组分成比特列表,每个比特数组有32位(15936/32 = 498比特列表)。

无法准确找到如何划分bitarray。请帮忙。

谢谢,

2 个答案:

答案 0 :(得分:2)

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

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();

如果那些按照与您预期相反的顺序为您提供位数组,请在Array.Reverse(values)调用后调用CopyTo

遗憾的是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();

答案 1 :(得分:1)

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

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));
}