有没有简单的方法可以连接两个BitArray(C# .NET)?

9

我有

var previous = new BitArray(new bool[]{true});
var current = new BitArray(new bool[]{false});

我想要将它们连接起来。我已经尝试过:

var next = new BitArray(previous.Count + current.Count);
var index = 0;
for(;index < previous.Count; index++)
    next[index] = previous[index];
var j = 0;
for(;index < next.Count; index++, j++)
    next[index] = current[j];
previous = current;

但这似乎并不是最好的方法。
5个回答

10

很遗憾,看起来您的方法可能已经达到了最佳效果 - 如果BitArray实现了IEnumerable<T>(而不仅仅是IEnumerable),那么我们可以使用LINQ扩展方法使其看起来更漂亮。

如果我是您,我会将其封装成BitArray的扩展方法:

public static BitArray Prepend(this BitArray current, BitArray before) {
    var bools = new bool[current.Count + before.Count];
    before.CopyTo(bools, 0);
    current.CopyTo(bools, before.Count);
    return new BitArray(bools);
}

public static BitArray Append(this BitArray current, BitArray after) {
    var bools = new bool[current.Count + after.Count];
    current.CopyTo(bools, 0);
    after.CopyTo(bools, current.Count);
    return new BitArray(bools);
}

2
如果您知道第一个数组包含32位的偶数倍,那么您可以通过使用int数组而不是bool数组来显着优化此过程。CopyTo可与int[]、bool[]和byte[]一起使用。 - Curt Hagenlocher

6

可以使用LINQ来实现此操作,在 Cast<bool>() 之后,位数组将会“变成”IEnumerable<bool>

var previous = new BitArray(new bool[] { true });
var current = new BitArray(new bool[] { false });

BitArray newBitArray = 
    new BitArray(previous.Cast<bool>().Concat(current.Cast<bool>()).ToArray());

我认为这个LINQ方法不会很快。


2

这个框架没有提供一个很好的方法来做到这一点。您可以创建一个足够大的布尔数组来存储两个BitArray,然后使用BitArray.CopyTo将每个BitArray复制到布尔数组中(您可以指定从哪里开始插入元素)。

完成这个步骤后,使用接受布尔数组作为参数的构造函数创建另一个BitArray。

我知道这需要做很多工作,但似乎没有其他方法。不过,它比您当前的方法要少些代码。


0
这是我的 LINQ 实现,它不包括必须分配布尔数组的开销:
var result = new BitArray(first.Count + second.Count);

var i = 0;
foreach (var value in first.Cast<bool>().Concat(second.Cast<bool>()))
{
    result[i++] = value;
}

-1

如果你使用int32而不是bools,那么效率会更高,因为bitarray在内部使用int32。

public static BitArray Append(this BitArray current, BitArray after) {
    var ints = new int[(current.Count + after.Count) / 32];
    current.CopyTo(ints, 0);
    after.CopyTo(ints, current.Count / 32);
    return new BitArray(ints);
}

如果有人需要,这是VB.NET中的代码:

<Runtime.CompilerServices.Extension()> _
Public Function Append(ByVal current As BitArray, ByVal after As BitArray) As BitArray
    Dim ints = New Int32((current.Count + after.Count) \ 32 - 1) {}
    current.CopyTo(ints, 0)
    after.CopyTo(ints, current.Count \ 32)
    Return New BitArray(ints)
End Function

2
这段代码只有在两个输入的位数组长度都是32的倍数时才能正常工作 - 否则会出现越界异常,因为32除法会向下取整,使得“ints”太短。即使让“ints”变长也不足以解决问题,因为除非“current”长度是32的倍数,否则附加的数组将在中间留下未使用的位,这可能不是我们想要的结果。 - Kristian Wedberg
好主意,但正如@KristianWedberg所提到的,这只在某些(罕见的)情况下才能起作用。 - larsmoa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接