2011-01-25 37 views
6

私は、C#でBitArrayの順序を逆転させる最も効率的な方法を知りました。はっきりするように、私は.Not()を呼び出すことによってBitarrayを逆にしたくないので、配列のビットの順序を逆にしたいと思います。BitArrayの順序を逆転する最も効率的な方法は?

乾杯、長いアレイと相対数の用途のため クリス

+0

に> LSB XORを使用して任意の長さのは、固定サイズのですか? –

+6

それを逆に使って(読んで)どうですか? –

+0

はい、サイズは固定です(8ビット) – Christopher

答えて

24
public void Reverse(BitArray array) 
{ 
    int length = array.Length; 
    int mid = (length/2); 

    for (int i = 0; i < mid; i++) 
    { 
     bool bit = array[i]; 
     array[i] = array[length - i - 1]; 
     array[length - i - 1] = bit; 
    }  
} 
+0

これは私が10kに誰かをupvotedした4回目のようなものです。それらのモデレータツールをお楽しみください! – codekaizen

+4

@codekaizen歓声 - 私は死んだ質問を見ることができます:) –

5

、それを包む:

class BitArrayReverse 
    { 
     private BitArray _ba; 

     public BitArrayReverse(BitArray ba) { _ba = ba; } 

     public bool this[int index] 
     { 
      get { return _ba[_ba.Length - 1 - index]; } 
      set { _ba[_ba.Length - 1 - index] = value; } 
     } 

    } 
+0

+1ニース。実際には答えはありませんが、いくつかの状況では巧妙なオプションです。 – Tomas

0

サイズので、単に「テーブル」の8ビットに固定されている場合下からのルックアップで十分です - 平文を扱う場合はbyteルックアップが最も簡単です。しかし、データを取得/設定するためのBitSetの余分なオーバーヘッドがルックアップの利益を無効にする可能性があります。

8ビット(これまでのバージョン)のデータがある場合は、最初のビルドコストと永続的なオーバーヘッドを考慮する必要があります。 、 "パフォーマンスは重要です"、なぜBitArrayを使うのですか? BitArrayはEnumerableへの "exploding"のような素敵な機能のためにいつも使うことができましたが、C#にはまともなバイトビット操作が組み込まれています。

データは8ビットの整列されていることを、より一般的なケースを想定し...しかし、いくつかの不確定な長さ

のそれ「の項目ごとに行うよりも、この実際にはより良い(など、より速く、より効率的な)です"BitArrayで? はわかりませんが、そうは思わないです。私は間違いなく "シンプル"な方法から始めます。これは単なる概念実証的なものであり、ベンチマークで比較するのが面白いかもしれません。とにかく、最初に明瞭に書いてください ...そしてそれはそれではありません! (少なくとも1つのバグがそれである - 私は、余分な複雑さを責める;-)

byte reverse (byte b) { 
    byte o = 0; 
    for (var i = 0; i < 8; i++) { 
     o <<= 1; 
     o |= (byte)(b & 1); 
     b >>= 1; 
    } 
    return o; 
} 

byte[] table; 
BitArray reverse8 (BitArray ar) { 
    if (ar.Count % 8 != 0) { 
     throw new Exception("no!"); 
    } 

    byte[] d = new byte[ar.Count/8]; 
    ar.CopyTo(d, 0); 

    // this only works if the bit array is 
    // a multiple of 8. we swap bytes and 
    // then reverse bits in each byte 
    int mid = d.Length/2; 
    for (int i = 0, j = d.Length - 1; i < mid; i++, j--) { 
     byte t = d[i]; 
     d[i] = table[d[j]]; 
     d[j] = table[t]; 
    } 

    return new BitArray(d); 
} 

string tostr (BitArray x) { 
    return string.Join("", 
     x.OfType<bool>().Select(i => i ? "1" : "0").ToArray()); 
} 

void Main() 
{ 
    table = Enumerable.Range(0,256).Select(v => reverse((byte)v)).ToArray(); 
    { 
     byte[] s = new byte[] { 1, 0xff }; 
     BitArray ar = new BitArray(s); 
     // linqpad :) 
     tostr(ar).Dump(); 
     tostr(reverse8(ar)).Dump(); 
    } 
    "--".Dump(); 
    { 
     byte[] s = new byte[] { 3, 42, 19 }; 
     BitArray ar = new BitArray(s); 
     // linqpad :) 
     tostr(ar).Dump(); 
     tostr(reverse8(ar)).Dump(); 
    } 
} 

出力:

1000000011111111 
1111111100000001 
-- 
110000000101010011001000 
000100110101010000000011 

expr.Dump()LINQPad機能です。

4

これはMSB <逆にする最善の方法 になります - ループの

public static BitArray BitsReverse(BitArray bits) 
{ 
    int len = bits.Count; 
    BitArray a = new BitArray(bits); 
    BitArray b = new BitArray(bits); 

    for (int i = 0, j = len-1; i < len; ++i, --j) 
    { 
     a[i] = a[i]^b[j]; 
     b[j] = a[i]^b[j]; 
     a[i] = a[i]^b[j]; 
    } 

    return a; 
} 
// in 010000011010000011100b 
// out 001110000010110000010b 
1
Dim myBA As New BitArray(4) 
myBA(0) = True 
myBA(1) = False 
myBA(2) = True 
myBA(3) = True 
Dim myBoolArray1(3) As Boolean 
myBA.CopyTo(myBoolArray1, 0) 
Array.Reverse(myBoolArray1) 
myBA = New BitArray(myBoolArray1) 
関連する問題