2011-08-07 7 views
20

JavaScriptでビット配列を実装する最適な方法は何ですか?Javascriptでビット配列を作成するにはどうすればよいですか?

+6

あなたが直面している問題を教えてください。 –

+3

問題はありません。それは単に学習目的のためです。 – DrStrangeLove

+1

ビット配列を模倣できるかもしれませんが、各配列要素はまだバイト単位で格納されていると思いますので、メモリのメリットは得られません。 – vol7ron

答えて

16

は、ここに私が手早く一つだん:

UPDATEを - このクラスについての何かが一日中、私を悩ませていた - 作成 - サイズベースではなかったですN個のスロット/ビットを持つBitArrayは2段階の操作で、インスタンス化、サイズ変更を行いました。クラス値を、オプションの2番目のパラメータで更新し、サイズベースのインスタンスに配列の値または10進数の数値を設定しました。 @Daniel Baulig TO

(それhereとフィドル)

/* BitArray DataType */ 

// Constructor 
function BitArray(size, bits) { 
    // Private field - array for our bits 
    this.m_bits = new Array(); 

    //.ctor - initialize as a copy of an array of true/false or from a numeric value 
    if (bits && bits.length) { 
     for (var i = 0; i < bits.length; i++) 
      this.m_bits.push(bits[i] ? BitArray._ON : BitArray._OFF); 
    } else if (!isNaN(bits)) { 
     this.m_bits = BitArray.shred(bits).m_bits; 

    } 
    if (size && this.m_bits.length != size) { 
     if (this.m_bits.length < size) { 
      for (var i = this.m_bits.length; i < size; i++) { 
       this.m_bits.push(BitArray._OFF); 
      } 
     } else { 
      for(var i = size; i > this.m_bits.length; i--){ 
       this.m_bits.pop(); 
      } 
     } 
    } 
} 

/* BitArray PUBLIC INSTANCE METHODS */ 

// read-only property - number of bits 
BitArray.prototype.getLength = function() { return this.m_bits.length; }; 

// accessor - get bit at index 
BitArray.prototype.getAt = function (index) { 
    if (index < this.m_bits.length) { 
     return this.m_bits[index]; 
    } 
    return null; 
}; 
// accessor - set bit at index 
BitArray.prototype.setAt = function (index, value) { 
    if (index < this.m_bits.length) { 
     this.m_bits[index] = value ? BitArray._ON : BitArray._OFF; 
    } 
}; 

// resize the bit array (append new false/0 indexes) 
BitArray.prototype.resize = function (newSize) { 
    var tmp = new Array(); 
    for (var i = 0; i < newSize; i++) { 
     if (i < this.m_bits.length) { 
      tmp.push(this.m_bits[i]); 
     } else { 
      tmp.push(BitArray._OFF); 
     } 
    } 
    this.m_bits = tmp; 
}; 

// Get the complimentary bit array (i.e., 01 compliments 10) 
BitArray.prototype.getCompliment = function() { 
    var result = new BitArray(this.m_bits.length); 
    for (var i = 0; i < this.m_bits.length; i++) { 
     result.setAt(i, this.m_bits[i] ? BitArray._OFF : BitArray._ON); 
    } 
    return result; 
}; 

// Get the string representation ("101010") 
BitArray.prototype.toString = function() { 
    var s = new String(); 
    for (var i = 0; i < this.m_bits.length; i++) { 
     s = s.concat(this.m_bits[i] === BitArray._ON ? "1" : "0"); 
    } 
    return s; 
}; 

// Get the numeric value 
BitArray.prototype.toNumber = function() { 
    var pow = 0; 
    var n = 0; 
    for (var i = this.m_bits.length - 1; i >= 0; i--) { 
     if (this.m_bits[i] === BitArray._ON) { 
      n += Math.pow(2, pow); 
     } 
     pow++; 
    } 
    return n; 
}; 

/* STATIC METHODS */ 

// Get the union of two bit arrays 
BitArray.getUnion = function (bitArray1, bitArray2) { 
    var len = BitArray._getLen(bitArray1, bitArray2, true); 
    var result = new BitArray(len); 
    for (var i = 0; i < len; i++) { 
     result.setAt(i, BitArray._union(bitArray1.getAt(i), bitArray2.getAt(i))); 
    } 
    return result; 
}; 

// Get the intersection of two bit arrays 
BitArray.getIntersection = function (bitArray1, bitArray2) { 
    var len = BitArray._getLen(bitArray1, bitArray2, true); 
    var result = new BitArray(len); 
    for (var i = 0; i < len; i++) { 
     result.setAt(i, BitArray._intersect(bitArray1.getAt(i), bitArray2.getAt(i))); 
    } 
    return result; 
}; 

// Get the difference between to bit arrays 
BitArray.getDifference = function (bitArray1, bitArray2) { 
    var len = BitArray._getLen(bitArray1, bitArray2, true); 
    var result = new BitArray(len); 
    for (var i = 0; i < len; i++) { 
     result.setAt(i, BitArray._difference(bitArray1.getAt(i), bitArray2.getAt(i))); 
    } 
    return result; 
}; 

// Convert a number into a bit array 
BitArray.shred = function (number) { 
    var bits = new Array(); 
    var q = number; 
    do { 
     bits.push(q % 2); 
     q = Math.floor(q/2); 
    } while (q > 0); 
    return new BitArray(bits.length, bits.reverse()); 
}; 

/* BitArray PRIVATE STATIC CONSTANTS */ 
BitArray._ON = 1; 
BitArray._OFF = 0; 

/* BitArray PRIVATE STATIC METHODS */ 

// Calculate the intersection of two bits 
BitArray._intersect = function (bit1, bit2) { 
    return bit1 === BitArray._ON && bit2 === BitArray._ON ? BitArray._ON : BitArray._OFF; 
}; 

// Calculate the union of two bits 
BitArray._union = function (bit1, bit2) { 
    return bit1 === BitArray._ON || bit2 === BitArray._ON ? BitArray._ON : BitArray._OFF; 
}; 

// Calculate the difference of two bits 
BitArray._difference = function (bit1, bit2) { 
    return bit1 === BitArray._ON && bit2 !== BitArray._ON ? BitArray._ON : BitArray._OFF; 
}; 

// Get the longest or shortest (smallest) length of the two bit arrays 
BitArray._getLen = function (bitArray1, bitArray2, smallest) { 
    var l1 = bitArray1.getLength(); 
    var l2 = bitArray2.getLength(); 

    return l1 > l2 ? smallest ? l2 : l1 : smallest ? l2 : l1; 
}; 

CREDITベースのプロトタイプを作成するために迅速かつ汚いからリファクタリングを求めるため。

+0

+1になります。しかし、あなたの方法をコメントできますか? .ctorって何? – DrStrangeLove

+1

'' this''ではなく '' BitArray.prototype''に絶対にメソッドを追加する必要があります。 –

+0

であり、コンストラクタ関数が呼び出されるたびにすべてを再割り当てするべきではありません。私が提出した編集を見てください。 –

12

ビット配列についてはわかりませんが、新しい機能でバイト配列を簡単にすることができます。

ルックアップtyped arrays。私はこれらをChromeとFirefoxの両方で使用しました。重要なのはUint8Arrayです。 、Node.jsのため

var byte = arr[5]; 

Buffer(サーバー側)を使用:

var arr = new UintArray(512); 

そして(6バイト目)にアクセス:512初期化されていないバイトのアレイを作製するために

編集:

個々のビットにアクセスするには、ビットマスクを使用します。 1の位置にビットを取得するために

num & 0x1

+1

IEやFirefox 3.6のような広く普及しているブラウザではどうしますか? – Jiri

+0

Firefox 3.6は正常に動作するはずです。 IEの場合は、通常の配列を使用し、整数だけが入るようにしてください。ビットマスキングはまだ機能します。 – tjameson

+7

古いブラウザを無視するだけです。古いブラウザを使用している場合は、「申し訳ありませんが、実際のブラウザをダウンロードしてください。ここにいくつかのリンクがあります...」とユーザーに伝えてください。そうすれば、全世界が若干良い= D – tjameson

4

Stanford Javascript Crypto Library (SJCL)は、ビット配列の実装を提供し、異なる入力(16進文字列、バイト配列など)をビット配列に変換できます。

コードはGitHub:bitwiseshiftleft/sjclで公開されています。したがって、bitArray.jsを検索すると、ビット配列の実装を見つけることができます。

バイトからビットへの変換は、hereです。

関連する問題