2009-02-05 24 views
6

que tienen¿Hay alguna manera simple de concatenar dos BitArray (C# .NET)?

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

que desea concatenar ellos. Ya lo he intentado:

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; 

Pero no parece la mejor manera de hacerlo.

Respuesta

7

Desafortunadamente, parece que su método podría ser tan bueno como sea posible: si BitArray implementó IEnumerable <T> (en lugar de solo IEnumerable) entonces podríamos usar los métodos de extensión LINQ para hacerlo un poco más bonito.

Si yo fuera usted, me gustaría terminar con esto en un método de extensión en 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

Si usted sabe que la primera matriz contiene un múltiplo par de 32 bits, puede optimizar esto significativamente utilizando matrices int en lugar de matrices bool. CopyTo funciona con int [], bool [] y byte [] –

2

El marco no proporciona una buena manera de hacer esto. Podría crear una matriz de bools que sea lo suficientemente grande como para almacenar ambas BitArrays. Luego use BitArray.CopyTo para copiar cada BitArray en la matriz de bools (puede especificar dónde comenzar a insertar los elementos).

Una vez hecho esto, cree otro BitArray con el constructor que acepte una matriz de bools.

Mucho trabajo que conozco, pero parece que no hay otra manera. Sin embargo, es menos código que tu método actual.

5

Uno puede hacer esto con LINQ, después de Cast<bool>() la BitArray 'se convierte en' 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()); 

no creo que este método de LINQ será rápido.

-1

Es más eficiente si usa int32 en lugar de bools porque bitarray usa int32 internamente.

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

En Vb.net si alguien lo necesita:

<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

Este código solo funciona si ambas matrices de bits tienen longitudes que son múltiplos de 32; de lo contrario, se obtiene una excepción de fuera de límites ya que la división entera por 32 redondea el resultado , haciendo 'ints' demasiado cortos. Hacer 'ints' más largos tampoco es suficiente, ya que a menos que la longitud 'actual' sea un múltiplo de 32, la matriz adjunta dejará bits no utilizados en el medio, lo que probablemente no sea lo que uno quiere. –

+0

Buena idea, pero como @KristianWedberg menciona que esto solo funcionará bajo ciertas (raras) condiciones. – larsmoa

0

Aquí está mi aplicación de LINQ que no incluye la sobrecarga de tener que asignar una matriz de Bools:

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; 
} 
Cuestiones relacionadas