2011-08-07 58 views

回答

16

这里有一个我掀起了:

更新 - 一些关于这个课堂上一直困扰着我整天 - 它不是基于大小 - 创建具有N个插槽/位的BitArray是两步操作 - 实例化,调整大小。使用可选的第二个参数更新该类的大小,以便使用数组值或基数为10的数值填充基于大小的实例。

(拨弄它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; 
}; 

信贷@Daniel Baulig询问从快速和肮脏的基于原型的重构。

+0

+1。但是,请问您可以评论您的方法吗?什么是.ctor? – DrStrangeLove

+1

你应该绝对将方法添加到''BitArray.prototype''而不是''this''。 –

+0

,每次调用构造函数时都不应该重新分配所有这些。请参阅我提交的修改。 –

12

我不知道位数组,但是可以使用新功能轻松地创建字节数组。

查找typed arrays。我在Chrome和Firefox中都使用过这些。重要的是Uint8Array。

为了使512个未初始化字节的数组:

var arr = new UintArray(512); 

和访问它(第六个字节):

var byte = arr[5]; 

对于node.js的,使用Buffer(服务器端)。

编辑:

访问各个位,利用位掩码。

若要获取一个人的位置的位,做num & 0x1

+1

你将如何处理IE或Firefox 3.6等浏览器? – Jiri

+0

Firefox 3.6应该可以正常工作。对于IE,使用常规数组并确保只有整数进入。位掩码仍然可以工作。 – tjameson

+7

我完全不理会旧的浏览器。如果他们使用的是旧浏览器,请告诉用户:“对不起,请下载一个真正的浏览器,这里有几个链接......”。那会让整个世界变得更好= D – tjameson