typescript-algorithms-and-datastructures
Version:
Useful algorithms and Data structures written in typescript.
113 lines • 4.3 kB
JavaScript
(function (factory) {
if (typeof module === "object" && typeof module.exports === "object") {
var v = factory(require, exports);
if (v !== undefined) module.exports = v;
}
else if (typeof define === "function" && define.amd) {
define(["require", "exports"], factory);
}
})(function (require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
class BitArray {
constructor(size) {
this.length = 0;
this.length = size;
this.buffer = new Uint32Array(this.calculateBufferSize(this.length));
}
count() {
return this.buffer.reduce((total, chunk) => this.bitsCountInNumber(chunk) + total, 0);
}
get(index) {
this.validateIndex(index);
const chunkOffset = Math.floor(index / 32);
const bitOffset = index - chunkOffset * 32;
return !!(this.buffer[chunkOffset] & (1 << bitOffset));
}
getIndexes() {
let result = [];
let bitIndex = 0;
let bit = false;
while (bitIndex < this.length) {
bit = this.get(bitIndex);
if (bit) {
result.push(bitIndex);
}
bitIndex++;
}
return result;
}
reset() {
this.buffer.fill(0);
return this;
}
resize(newSize) {
if (newSize < 0) {
throw new RangeError(`Invalid new BitSet size ${newSize}`);
}
const newBufferSize = this.calculateBufferSize(newSize);
this.length = newSize;
if (newBufferSize > this.buffer.length) {
const oldBuffer = this.buffer;
this.buffer = new Uint32Array(newBufferSize);
this.buffer.set(oldBuffer);
}
else if (newBufferSize < this.buffer.length) {
const oldBuffer = this.buffer;
this.buffer = new Uint32Array(newBufferSize);
this.buffer.set(oldBuffer.slice(0, newBufferSize));
}
return this;
}
size() {
return this.length;
}
splice(startIndex, deleteCount) {
if (isNaN(deleteCount) || deleteCount < 1) {
return;
}
if (startIndex < 0) {
startIndex = this.length + startIndex;
if (startIndex < 0) {
throw new RangeError(`${startIndex} is less than 0`);
}
}
else if (startIndex >= this.length) {
throw new RangeError(`${startIndex} exceeds the array size ${this.length}`);
}
const tempBuffer = this.getIndexes()
.filter(index => index < startIndex || index >= startIndex + deleteCount)
.map(index => index >= startIndex + deleteCount ? index - deleteCount : index);
this.reset();
this.resize(this.length - deleteCount);
tempBuffer.forEach(id => this.set(id, true));
}
set(index, value) {
this.validateIndex(index);
const chunkOffset = Math.floor(index / 32);
const offset = index - chunkOffset * 32;
if (value) {
this.buffer[chunkOffset] |= (1 << offset);
}
else {
this.buffer[chunkOffset] &= ~(1 << offset);
}
return this;
}
calculateBufferSize(bitsCount) {
return Math.ceil(bitsCount / 32) * 4;
}
bitsCountInNumber(value) {
value -= ((value >>> 1) & 0x55555555);
value = (value & 0x33333333) + ((value >>> 2) & 0x33333333);
return (((value + (value >>> 4) & 0xF0F0F0F) * 0x1010101) >>> 24);
}
validateIndex(index) {
if (index > this.length - 1 || index < 0) {
throw new RangeError("Index is too large.");
}
}
}
exports.BitArray = BitArray;
});
//# sourceMappingURL=BitArray.js.map