UNPKG

data-structure-typed

Version:
346 lines (302 loc) 9.75 kB
import { BinaryIndexedTree } from '../../../../src'; // import {isDebugTest} from '../../../config'; // const isDebug = isDebugTest; describe('BinaryIndexedTree simple', () => { let bit: BinaryIndexedTree; beforeEach(() => { //Create a new BinaryIndexedTree instance before each test case bit = new BinaryIndexedTree({ frequency: 0, max: 10 }); // Modify the value of max as needed }); it('should initialize correctly', () => { expect(bit.freq).toBe(0); expect(bit.max).toBe(10); expect(bit.freqMap).toEqual({ 0: 0 }); // Modify the initialized record value according to the actual situation // More initialization checks can be added }); it('should read a single value correctly', () => { // Test the function of reading a single value bit.writeSingle(5, 5); //Write test data expect(bit.readSingle(5)).toBe(5); // Read and verify }); it('should update a value correctly', () => { // Test the ability to update a single value bit.writeSingle(5, 5); //Write test data bit.update(5, 2); // update value expect(bit.readSingle(5)).toBe(7); // Verify the updated value }); it('should find lower bound correctly', () => { //Test the function of finding the lower bound bit.writeSingle(2, 10); bit.writeSingle(5, 20); bit.writeSingle(8, 30); expect(bit.lowerBound(15)).toBe(5); // Find and verify the lower bound }); it('should find upper bound correctly', () => { //Test the function of finding the upper bound bit.writeSingle(2, 10); bit.writeSingle(5, 20); bit.writeSingle(8, 30); expect(bit.upperBound(25)).toBe(5); // Find and verify the upper bound }); }); describe('BinaryIndexedTree', () => { const frequency = 999; const max = 10; let bit: BinaryIndexedTree; beforeEach(function () { bit = new BinaryIndexedTree({ frequency, max }); }); it('should validate the index', function () { expect(() => bit.readSingle(-1)).toThrow('Index out of range'); expect(() => bit.readSingle(10)).toThrow('Index out of range'); }); it('should read a single frequency correctly', function () { for (let i = 0; i < max; i++) { expect(bit.readSingle(i)).toBe(frequency); } }); it('should validate the index', function () { expect(() => bit.update(-1, 100)).toThrow('Index out of range'); expect(() => bit.update(10, 100)).toThrow('Index out of range'); }); it('should frequency and max', function () { const frequency = 200; const max = 1000; const bit = new BinaryIndexedTree({ frequency, max }); expect(bit.freq).toBe(frequency); expect(bit.max).toBe(max); }); it('should update the frequency with the given delta', function () { for (let i = 0; i < max; i++) { bit.update(i, i * 2); } for (let i = 0; i < max; i++) { expect(bit.readSingle(i)).toBe(i * 2 + frequency); } }); it('should validate the index', function () { expect(() => bit.writeSingle(-1, 100)).toThrow('Index out of range'); expect(() => bit.writeSingle(10, 100)).toThrow('Index out of range'); }); it('should writeSingle to be correctly invoked', function () { for (let i = 0; i < max; i++) { bit.writeSingle(i, i * 2); } for (let i = 0; i < max; i++) { expect(bit.readSingle(i)).toBe(i * 2); } }); it('should read the frequency', function () { for (let c = 0; c <= max; c++) { expect(bit.read(c)).toBe(c * frequency); } }); const values = [-5, 0, 5, 10, 95, 100, 1000]; it('should find the upper-bound index', function () { loopUpperBoundTests(bit, values); }); it('should find the lower-bound index', function () { loopLowerBoundTests(bit, values); }); }); describe('designated values', function () { const array = [1, 8, 6, 10, 7, 9, 0, 2, 6, 3]; const sumArray = (sum => array.map(value => (sum += value)))(0); let bit: BinaryIndexedTree; beforeEach(function () { bit = new BinaryIndexedTree({ max: array.length }); array.forEach((value, i) => bit.writeSingle(i, value)); }); describe('readSingle', function () { it('should read a single frequency correctly', function () { array.forEach((value, i) => { expect(bit.readSingle(i)).toBe(array[i]); }); }); }); describe('update', function () { it('should update the frequency with the given delta', function () { array.forEach((value, i) => bit.update(i, value + i)); array.forEach((value, i) => { expect(bit.readSingle(i)).toBe(array[i] * 2 + i); }); }); }); describe('writeSingle', function () { it('should write a single frequency correctly', function () { array.forEach((value, i) => bit.writeSingle(i, value + i)); array.forEach((value, i) => { expect(bit.readSingle(i)).toBe(array[i] + i); }); }); }); describe('read', function () { it('should read the cumulative frequency correctly', function () { expect(bit.read(0)).toBe(0); sumArray.forEach((sum, i) => { expect(bit.read(i + 1)).toBe(sum); }); }); }); const values = [-5, 0, 15, 25, 43, 53, 100]; describe('upperBound', function () { it('should find the upper-bound index', function () { loopUpperBoundTests(bit, values); }); }); describe('lowerBound', function () { it('should find the lower-bound index', function () { loopLowerBoundTests(bit, values); }); }); }); describe('descending sequence', function () { const array = [1, 8, -6, 10, 7, 9, 0, -2, 6, 3]; let bit: BinaryIndexedTree; beforeEach(function () { bit = new BinaryIndexedTree({ max: array.length }); array.forEach((value, i) => bit.writeSingle(i, value)); }); it('should have a correct negativeCount property', function () { expect(bit.negativeCount).toBe(2); bit.update(2, 6); expect(bit.negativeCount).toBe(1); bit.update(7, 3); expect(bit.negativeCount).toBe(0); bit.update(8, -7); expect(bit.negativeCount).toBe(1); }); const values = [-5, 0, 15, 25, 43, 53, 100]; describe('upperBound', function () { it('should validate the non-descending', function () { expect(() => bit.upperBound(20)).toThrow('Must not be descending'); bit.update(2, 12); bit.update(7, 4); loopUpperBoundTests(bit, values); }); }); describe('BinaryIndexedTree lowerBound', function () { it('should validate the non-descending', function () { expect(() => bit.lowerBound(20)).toThrow('Sequence is not non-descending'); bit.update(2, 12); bit.update(7, 4); loopLowerBoundTests(bit, values); }); }); }); describe('BinaryIndexedTree additional tests', () => { it('should handle read method correctly', () => { const bit = new BinaryIndexedTree({ max: 10 }); bit.writeSingle(2, 10); bit.writeSingle(5, 20); bit.writeSingle(8, 30); expect(bit.read(5)).toBe(10); // Ensure read method accumulates correctly }); it('should handle consecutive operations', () => { const bit = new BinaryIndexedTree({ max: 10 }); bit.writeSingle(2, 10); bit.update(2, 5); expect(bit.readSingle(2)).toBe(15); bit.writeSingle(5, 20); expect(bit.readSingle(5)).toBe(20); expect(bit.lowerBound(15)).toBe(2); }); it('should handle frequent increment updates', () => { const bit = new BinaryIndexedTree({ max: 10 }); for (let i = 0; i < 10; i++) { bit.update(2, 5); } expect(bit.readSingle(2)).toBe(50); }); it('should handle edge cases', () => { const bit = new BinaryIndexedTree({ max: 10 }); bit.writeSingle(9, 100); expect(bit.readSingle(9)).toBe(100); expect(bit.lowerBound(200)).toBe(10); }); }); function loopUpperBoundTests(bit: BinaryIndexedTree, values: number[]) { for (const value of values) { const index = bit.upperBound(value); if (index > 0) { expect(bit.read(index)).toBeLessThanOrEqual(value); } else { expect(index).toBe(0); } if (index < bit.max) { expect(bit.read(index + 1)).toBeGreaterThan(value); } else { expect(index).toBe(bit.max); } } } function loopLowerBoundTests(bit: BinaryIndexedTree, values: number[]) { for (const value of values) { const index = bit.lowerBound(value); if (index > 0) { expect(bit.read(index)).toBeLessThan(value); } else { expect(index).toBe(0); } if (index < bit.max) { expect(bit.read(index + 1)).toBeGreaterThanOrEqual(value); } else { expect(index).toBe(bit.max); } } } describe('', () => { class NumArrayDC { protected _tree: BinaryIndexedTree; protected readonly _nums: number[]; constructor(nums: number[]) { this._nums = nums; this._tree = new BinaryIndexedTree({ max: nums.length + 1 }); for (let i = 0; i < nums.length; i++) { this._tree.update(i + 1, nums[i]); } } update(index: number, value: number): void { this._tree.update(index + 1, value - this._nums[index]); this._nums[index] = value; } sumRange(left: number, right: number): number { return this._tree.getPrefixSum(right + 1) - this._tree.getPrefixSum(left); } } it('', () => { const numArray = new NumArrayDC([1, 3, 5, 8, 2, 9, 4, 5, 8, 1, 3, 2]); expect(numArray.sumRange(0, 8)).toBe(45); expect(numArray.sumRange(0, 2)).toBe(9); numArray.update(1, 2); expect(numArray.sumRange(0, 2)).toBe(8); expect(numArray.sumRange(3, 4)).toBe(10); numArray.update(3, 2); expect(numArray.sumRange(3, 4)).toBe(4); }); });