【问题标题】:Is there any simple way to concatenate two BitArray (C# .NET)?有没有简单的方法来连接两个 BitArray (C# .NET)?
【发布时间】:2010-10-05 20:00:24
【问题描述】:

我有

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;

但这看起来并不是最好的方法。

【问题讨论】:

    标签: c# .net bitarray


    【解决方案1】:

    不幸的是,您的方法看起来可能和它一样好 - 如果 BitArray 实现了 IEnumerable(而不仅仅是 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);
    }
    

    【讨论】:

    • 如果您知道第一个数组包含 32 位的偶数倍数,则可以通过使用 int 数组而不是 bool 数组来显着优化这一点。 CopyTo 适用于 int[]、bool[] 和 byte[]
    【解决方案2】:

    Cast&lt;bool&gt;() 位数组“变成”IEnumerable&lt;bool&gt; 之后,可以使用 LINQ 做到这一点:

    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 方法不会很快。

    【讨论】:

      【解决方案3】:

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

      完成后,使用接受布尔数组的构造函数创建另一个 BitArray。

      我知道很多工作,但似乎没有其他方法。但是,它的代码比您当前的方法少。

      【讨论】:

        【解决方案4】:

        这是我的 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;
        }
        

        【讨论】:

          【解决方案5】:

          如果使用 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
          

          【讨论】:

          • 此代码仅在两个传入位数组的长度都是 32 的倍数时才有效 - 否则会出现越界异常,因为整数除以 32 会将结果向下舍入,从而使“整数”太短.使“整数”更长也是不够的,因为除非“当前”长度是 32 的倍数,否则附加的数组将在中间留下未使用的位,这可能不是人们想要的。
          • 好主意,但正如@KristianWedberg 所提到的,这仅在某些(罕见)条件下有效。
          猜你喜欢
          • 1970-01-01
          • 2011-04-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-10-14
          相关资源
          最近更新 更多