diff --git a/.eslintrc.json b/.eslintrc.json index 1b2f056..5d76fd8 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -13,9 +13,22 @@ }, "rules": { "camelcase": ["off"], + "class-methods-use-this": ["warn"], + "comma-dangle": ["error"], "eqeqeq": ["off"], - "linebreak-style": ["error", "windows"], + "linebreak-style": ["off"], "max-len": ["warn"], - "no-plusplus":["off"] + "no-array-constructor": ["warn"], + "no-bitwise": ["off"], + "no-console": ["error"], // eslint-disable-line no-console if you wish to deliberately use console + "no-continue": ["off"], + "no-new-object": ["off"], + "no-param-reassign": ["off"], + "no-plusplus": ["off"], + "no-restricted-syntax": ["warn"], + "no-shadow": ["off"], + "no-underscore-dangle": ["off"], + "quotes" :["off"], + "strict": ["off"] } } diff --git a/.travis.yml b/.travis.yml index ce0dbde..65e5756 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,13 +3,13 @@ sudo: false language: node_js node_js: - - 10.5 + - 10.15.0 install: - npm install script: - #- npm run lint + - npm run lint - npm test - npm run prod - npm run test:coveralls diff --git a/package.json b/package.json index 0c8f95d..926e5dc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "string-dsa", - "version": "1.2.1", + "version": "1.2.2", "description": "String Data Structures and Algorithms Library in JavaScript", "main": "src/index.js", "files": [ @@ -8,12 +8,11 @@ "src" ], "scripts": { - "coverage": "nyc npm test", - "dev": "webpack -d", - "lint": "eslint ./src ./test", + "coverage": "nyc npm test", + "lint": "eslint ./src", "test": "mocha --recursive", "test:coveralls": "npm run coverage && nyc report --reporter=text-lcov | coveralls", - "prod": "webpack -p" + "prod": "webpack -d" }, "repository": { "type": "git", diff --git a/src/BloomFilter.js b/src/BloomFilter.js index f951f73..00f8a9d 100644 --- a/src/BloomFilter.js +++ b/src/BloomFilter.js @@ -1,108 +1,103 @@ "use strict"; -/**Class implementation of Bloom Filter */ -class BF{ - /** - * +/** Class implementation of Bloom Filter */ +class BF { + /** + * * @param {Number} buckets The number of buckets for the hash function * @param {Number} splits The number of splits you wish to have * @param {Function[]} customHashFn custom hashing function - * + * * @returns {BF} the demanded Bloom Filter */ - constructor(buckets, splits,customHashFn = null){ - this._bucketSize = buckets; - this._splitSize = splits; - this.bucket = new Array(); - this._useInternalHashFn = true; - this._customHashFn = undefined; - this._insertionCount = 0; + constructor(buckets, splits, customHashFn = null) { + this._bucketSize = buckets; + this._splitSize = splits; + this.bucket = new Array(); + this._useInternalHashFn = true; + this._customHashFn = undefined; + this._insertionCount = 0; - for (let x = 0; x < this._splitSize; x++){ - let internalArray = new Array(this._bucketSize); - for (let y = 0; y< this._bucketSize; y++) internalArray[y] = false; - this.bucket.push(internalArray); - } - - if (customHashFn != null && customHashFn.length == splits){ - this._useInternalHashFn = false; - this._customHashFn = customHashFn; - } else { - this._customHashFn = []; - for(let i=1; i { - return (x) => { - let hash_value = 0; - for (let j=0;j (x) => { + let hash_value = 0; + for (let j = 0; j < x.length; j++) { + hash_value *= i; + hash_value += x.charCodeAt(j); + hash_value %= this._bucketSize; + } + return hash_value; + })(i)); + } } + } - /** - * - * @param {Object} elem Object that you wish to insert into the Bloom Filter (Should possess toString Property !!) - */ - insert(elem){ - try { - let elem_string = elem.toString(); + get bucketSize() { + return this._bucketSize; + } - for (let i=0; i count - let startpos; let currentGram = ""; - for (startpos = 0; startpos < str.length; startpos += 1) { - currentGram += str[startpos] + const gramSplit = new Map(); // gram <-> count + let currentGram = ''; + for (let startpos = 0; startpos < str.length; startpos += 1) { + currentGram += str[startpos]; if (startpos >= n - 1) { if (gramSplit.has(currentGram)) { - gramSplit.set(currentGram,gramSplit.get(currentGram) + 1) + gramSplit.set(currentGram, gramSplit.get(currentGram) + 1); } else { - gramSplit.set(currentGram,1) + gramSplit.set(currentGram, 1); } - currentGram = currentGram.substr(1) + currentGram = currentGram.substr(1); } - } - return gramSplit -}; + } + return gramSplit; +} function min(a, b) { return a > b ? b : a; -}; +} /** * Returns the computed Dice Coefficient for the given n-gram of the two strings @@ -28,34 +28,32 @@ function min(a, b) { * @return {Number} a number between 0 and 1 */ function computeDice(st1, st2, n) { - if (st1.length < 1 || st2.length < 1 || n > min(st1.length, st2.length)) return -1; - mapSt1 = nGram(st1, n) - mapSt2 = nGram(st2, n) - + const mapSt1 = nGram(st1, n); + const mapSt2 = nGram(st2, n); + let sharedValueCount = 0; - - for (let x of mapSt1.keys()){ - if(mapSt2.has(x)){ - sharedValueCount += min(mapSt1.get(x), mapSt2.get(x)); + + for (const x of mapSt1.keys()) { + if (mapSt2.has(x)) { + sharedValueCount += min(mapSt1.get(x), mapSt2.get(x)); } } - - let st1ValueCount = 0,st2ValueCount = 0; - - for (let x of mapSt1.keys()){ - st1ValueCount += mapSt1.get(x) + + let st1ValueCount = 0; let st2ValueCount = 0; + + for (const x of mapSt1.keys()) { + st1ValueCount += mapSt1.get(x); } - - for (let x of mapSt2.keys()){ - st2ValueCount += mapSt2.get(x) + + for (const x of mapSt2.keys()) { + st2ValueCount += mapSt2.get(x); } - - let score = (2 * sharedValueCount) / (st1ValueCount + st2ValueCount) - - return score - //score = 2*sharedValueCount/ (st1ValueCount + st2ValueCount) + + const score = (2 * sharedValueCount) / (st1ValueCount + st2ValueCount); + + return score; } module.exports = computeDice; diff --git a/src/edit_distance.js b/src/edit_distance.js index 2a594a3..d844d8f 100644 --- a/src/edit_distance.js +++ b/src/edit_distance.js @@ -1,39 +1,39 @@ -function min(a,b){ - return a < b ? a : b; +function min(a, b) { + return a < b ? a : b; } /** Finds the Edit distance between two strings - * + * * @param {String} string1 the first string * @param {String} string2 the second string - * + * * @returns {Number} states the edit distance between two strings */ function editDistance(string1, string2) { - editDistanceMatrix = new Array(); + const editDistanceMatrix = new Array(); - for(let i = 0; i< string1.length + 1; i++) { - editDistanceMatrix.push(new Array(string2.length + 1)); - } + for (let i = 0; i < string1.length + 1; i++) { + editDistanceMatrix.push(new Array(string2.length + 1)); + } - for(let i = 0; i< string2.length + 1; i++){ - editDistanceMatrix[0][i] = i; - } + for (let i = 0; i < string2.length + 1; i++) { + editDistanceMatrix[0][i] = i; + } - for(let i = 0; i< string1.length + 1; i++){ - editDistanceMatrix[i][0] = i; - } + for (let i = 0; i < string1.length + 1; i++) { + editDistanceMatrix[i][0] = i; + } - for(let i = 1; ib ? a : b; +function max(a, b) { + return a > b ? a : b; } /** - * + * * @param {String} string1 the first string to be used in LCS search * @param {String} string2 the second string to be used in LCS search - * + * * @return {Number} the largest common substring size */ -function lcs(string1,string2) { - if(!(string1.length & string1.length)){ - return 0; +function lcs(string1, string2) { + if (!(string1.length & string1.length)) { + return 0; + } + const matchMatrix = Array(); + for (let i = 0; i <= string1.length; i++) { + const emptyArray = Array(); + for (let j = 0; j <= string2.length; j++) { + emptyArray.push(0); } - let matchMatrix = Array(); - for (let i=0; i<=string1.length; i++){ - let emptyArray = Array(); - for (let j=0; j<=string2.length ;j++){ - emptyArray.push(0); - } - matchMatrix.push(emptyArray) - } + matchMatrix.push(emptyArray); + } - for(let i1 = 0; i1<=string1.length; i1++){ - matchMatrix[i1][0] = 0 - } + for (let i1 = 0; i1 <= string1.length; i1++) { + matchMatrix[i1][0] = 0; + } - for (let i2 =0; i2<=string2.length; i2++){ - matchMatrix[0][i2] = 0 - } + for (let i2 = 0; i2 <= string2.length; i2++) { + matchMatrix[0][i2] = 0; + } - for(let i1=1; i1<=string1.length; i1++){ - for(let i2=1; i2<=string2.length; i2++){ - if( string1[i1 - 1] == string2[i2 - 1] ) { - matchMatrix[i1][i2] = matchMatrix[i1 -1][i2 -1] + 1 - } else { - matchMatrix[i1][i2] = max(max(matchMatrix[i1 -1][i2 -1],matchMatrix[i1 -1][i2]),max(matchMatrix[i1 -1][i2 -1],matchMatrix[i1][i2 -1])) - } - } + for (let i1 = 1; i1 <= string1.length; i1++) { + for (let i2 = 1; i2 <= string2.length; i2++) { + if (string1[i1 - 1] == string2[i2 - 1]) { + matchMatrix[i1][i2] = matchMatrix[i1 - 1][i2 - 1] + 1; + } else { + matchMatrix[i1][i2] = max(max(matchMatrix[i1 - 1][i2 - 1], matchMatrix[i1 - 1][i2]), max(matchMatrix[i1 - 1][i2 - 1], matchMatrix[i1][i2 - 1])); + } } - return matchMatrix[string1.length][string2.length]; + } + return matchMatrix[string1.length][string2.length]; } -module.exports = lcs; \ No newline at end of file +module.exports = lcs; diff --git a/src/search/AhoCorasick.js b/src/search/AhoCorasick.js new file mode 100644 index 0000000..e229947 --- /dev/null +++ b/src/search/AhoCorasick.js @@ -0,0 +1,18 @@ +"use strict"; + +class AC { + /** + * + * @param {String[]} keywordList the list of keywords that you wish to use for searching + * @param {Number} maxStates the number of states that are allowed (maxStates >= total number of letters in keywordlist). Set as -1 to allow the algorithm to figure out by itself + */ + constructor(keywordList, maxStates = -1) { + this.totalStates = maxStates > 0 ? maxStates : keywordList.reduce((letterCount, str) => letterCount + str.length, 0); + } + + find(searchSpace) { + return searchSpace; + } +} + +module.exports = AC; diff --git a/src/stringSort.js b/src/stringSort.js index fa14fff..67065ba 100644 --- a/src/stringSort.js +++ b/src/stringSort.js @@ -1,111 +1,103 @@ -//This is the best performing comparitive sort using n*l*log(n) timing -//TODO: Burst Sort and Cantor Hashing for optimized sorting +function internalSort(indexArray, stringArray, internalComp) { + if (indexArray.length == 1) { + return indexArray; + } + const midpt = parseInt(indexArray.length / 2, 10); + const grandMerge = []; + const leftAr = indexArray.slice(0, midpt); + const rightAr = indexArray.slice(midpt, indexArray.length); + + let sortedLeft = internalSort(leftAr, stringArray, internalComp); + let sortedRight = internalSort(rightAr, stringArray, internalComp); + + while (sortedLeft.length && sortedRight.length) { + if (internalComp(stringArray[sortedLeft[0]], stringArray[sortedRight[0]]) <= 0) { + grandMerge.push(sortedLeft[0]); + sortedLeft = sortedLeft.slice(1); + } else { + grandMerge.push(sortedRight[0]); + sortedRight = sortedRight.slice(1); + } + } + + while (sortedLeft.length) { + grandMerge.push(sortedLeft[0]); + sortedLeft = sortedLeft.slice(1); + } + + while (sortedRight.length) { + grandMerge.push(sortedRight[0]); + sortedRight = sortedRight.slice(1); + } + // delete leftAr; delete rightAr; + + return grandMerge; +} /** * Returns index wise sorted array for a string array - * + * * @param {object[]} stringArray an Array of Objects * @param {boolean} byIndex set true if you want results returned by index * @param {Function} compartorFn implement your custom comparatorFn here ! * @returns {object[]} Array of index/object in sorted fashion */ -function sort(stringArray, byIndex = false, compartorFn = null){ - if(stringArray.length <1) return []; - - const internalComp = compartorFn === null ? (x,y) => { - let i=0; - while(i { + let i = 0; + while (i < x.length && i < y.length) { + if (x.charCodeAt(i) != y.charCodeAt(i)) { + return (x.charCodeAt(i) - y.charCodeAt(i)); + } + i++; } -} - -function internalSort(indexArray,stringArray,internalComp){ - if(indexArray.length == 1) { - return indexArray; - } else { - let midpt = parseInt(indexArray.length/2); - let grandMerge = [] - let leftAr = indexArray.slice(0,midpt) - let rightAr = indexArray.slice(midpt,indexArray.length) - - let sortedLeft = internalSort(leftAr,stringArray,internalComp); - let sortedRight = internalSort(rightAr,stringArray,internalComp); - - while(sortedLeft.length && sortedRight.length){ - if(internalComp(stringArray[sortedLeft[0]],stringArray[sortedRight[0]]) <= 0) { - grandMerge.push(sortedLeft[0]); - sortedLeft = sortedLeft.slice(1); - } else { - grandMerge.push(sortedRight[0]); - sortedRight = sortedRight.slice(1); - } - } + return (x.length - y.length); + } : compartorFn; + const indexArray = Array(stringArray.length); + for (let i = 0; i < stringArray.length; i++) indexArray[i] = i; - while(sortedLeft.length){ - grandMerge.push(sortedLeft[0]); - sortedLeft = sortedLeft.slice(1); - } + const result = internalSort(indexArray, stringArray, internalComp); - while(sortedRight.length){ - grandMerge.push(sortedRight[0]); - sortedRight = sortedRight.slice(1); - } - //delete leftAr; delete rightAr; - - return grandMerge; - } + if (byIndex) { + return result; + } + const valueResult = []; + for (let i = 0; i < result.length; i++) { + valueResult.push(stringArray[result[i]]); + } + return valueResult; } /** - * + * * @param {object[]} array an Array of Objects * @param {Function} compartorFn comparator function - * + * * @returns {boolean} states whether the array is sorted or not */ -function sorted(array, compartorFn = null){ - if (array.length <2 ) return true; +function sorted(array, compartorFn = null) { + if (array.length < 2) return true; - const internalComp = compartorFn === null ? (x,y) => { - let i=0; - while(i0) return false; + const internalComp = compartorFn === null ? (x, y) => { + let i = 0; + while (i < x.length && i < y.length) { + if (x.charCodeAt(i) != y.charCodeAt(i)) { + return (x.charCodeAt(i) - y.charCodeAt(i)); + } + i++; } - return true; + return (x.length - y.length); + } : compartorFn; + + for (let x = 0; x < array.length - 1; x++) { + if (internalComp(array[x], array[x + 1]) > 0) return false; + } + return true; } module.exports = { - sort: sort, - sorted: sorted + sort, + sorted, }; diff --git a/src/suffix/index.js b/src/suffix/index.js new file mode 100644 index 0000000..e69de29 diff --git a/test/search/test_kmp.js b/test/search/test_kmp.js index 6b4e843..9daff37 100644 --- a/test/search/test_kmp.js +++ b/test/search/test_kmp.js @@ -1,36 +1,32 @@ -const kmp = require("../../src").kmp; const assert = require('assert'); - +const { kmp } = require("../../src"); describe('Knuth Morris Pratt', () => { - - const searchTerm1 = "cancan", searchTerm2 = "mixolydian", searchTerm3 = "pina"; - const searchSpace1 = "cancancan like a tin cancan?", searchSpace2 = "what even do you mean", searchSpace3 = "pina colada and what ?"; + const searchTerm1 = "cancan"; const searchTerm2 = "mixolydian"; const + searchTerm3 = "pina"; + const searchSpace1 = "cancancan like a tin cancan?"; const searchSpace2 = "what even do you mean"; const + searchSpace3 = "pina colada and what ?"; + + it(`should return index of "${searchTerm1}" in three positions for "${searchSpace1}"`, () => { + const result = kmp(searchTerm1, searchSpace1); + assert.deepStrictEqual(result, [0, 3, 21]); + }); - it(`should return index of "${searchTerm1}" in three positions for "${searchSpace1}"`, () => { - - const result = kmp(searchTerm1,searchSpace1) - assert.deepStrictEqual(result, [0,3,21]); - }); - - it(`should return [-1] for "${searchTerm2}" in "${searchSpace2}"`, () => { - - const result = kmp(searchTerm2,searchSpace2) - assert.deepStrictEqual(result, [-1]); - }); - - it(`should return one index for "${searchTerm3}" in "${searchSpace3}" `, () => { - - const result = kmp(searchTerm3,searchSpace3) - assert.deepStrictEqual(result, [0]); - }); + it(`should return [-1] for "${searchTerm2}" in "${searchSpace2}"`, () => { + const result = kmp(searchTerm2, searchSpace2); + assert.deepStrictEqual(result, [-1]); + }); - it('should return [-1] if either the searchTerm or searchSpace is empty', () => { + it(`should return one index for "${searchTerm3}" in "${searchSpace3}" `, () => { + const result = kmp(searchTerm3, searchSpace3); + assert.deepStrictEqual(result, [0]); + }); - const resultOne = kmp("",searchSpace1); - assert.deepStrictEqual(resultOne, [-1]); + it('should return [-1] if either the searchTerm or searchSpace is empty', () => { + const resultOne = kmp("", searchSpace1); + assert.deepStrictEqual(resultOne, [-1]); - const resultTwo = kmp(searchTerm1,""); - assert.deepStrictEqual(resultTwo, [-1]); - }); + const resultTwo = kmp(searchTerm1, ""); + assert.deepStrictEqual(resultTwo, [-1]); + }); }); diff --git a/test/search/test_rabin_karp.js b/test/search/test_rabin_karp.js index ccd6187..29a4920 100644 --- a/test/search/test_rabin_karp.js +++ b/test/search/test_rabin_karp.js @@ -1,36 +1,32 @@ -const rabin_karp = require("../../src").rabinKarp const assert = require('assert'); - +const rabin_karp = require("../../src").rabinKarp; describe('Rabin Karp', () => { - - const searchTerm1 = "cancan", searchTerm2 = "mixolydian", searchTerm3 = "pina"; - const searchSpace1 = "cancancan like a tin cancan?", searchSpace2 = "what even do you mean", searchSpace3 = "pina colada and what ?"; + const searchTerm1 = "cancan"; const searchTerm2 = "mixolydian"; const + searchTerm3 = "pina"; + const searchSpace1 = "cancancan like a tin cancan?"; const searchSpace2 = "what even do you mean"; const + searchSpace3 = "pina colada and what ?"; + + it(`should return index of ${searchTerm1} in three positions for ${searchSpace1}`, () => { + const result = rabin_karp(searchTerm1, searchSpace1); + assert.deepStrictEqual(result, [0, 3, 21]); + }); - it(`should return index of \"${searchTerm1}\" in three positions for \"${searchSpace1}\"`, () => { - - const result = rabin_karp(searchTerm1,searchSpace1) - assert.deepStrictEqual(result, [0,3,21]); - }); - - it(`should return [-1] for \"${searchTerm2}\" in \"${searchSpace2}\"`, () => { - - const result = rabin_karp(searchTerm2,searchSpace2) - assert.deepStrictEqual(result, [-1]); - }); - - it(`should return one index for \"${searchTerm3}\" in \"${searchSpace3}\" `, () => { - - const result = rabin_karp(searchTerm3,searchSpace3) - assert.deepStrictEqual(result, [0]); - }); + it(`should return [-1] for ${searchTerm2} in ${searchSpace2}`, () => { + const result = rabin_karp(searchTerm2, searchSpace2); + assert.deepStrictEqual(result, [-1]); + }); - it('should return [-1] if either the searchTerm or searchSpace is empty', () => { + it(`should return one index for ${searchTerm3} in ${searchSpace3} `, () => { + const result = rabin_karp(searchTerm3, searchSpace3); + assert.deepStrictEqual(result, [0]); + }); - const resultOne = rabin_karp("",searchSpace1); - assert.deepStrictEqual(resultOne, [-1]); + it('should return [-1] if either the searchTerm or searchSpace is empty', () => { + const resultOne = rabin_karp("", searchSpace1); + assert.deepStrictEqual(resultOne, [-1]); - const resultTwo = rabin_karp(searchTerm1,""); - assert.deepStrictEqual(resultTwo, [-1]); - }); + const resultTwo = rabin_karp(searchTerm1, ""); + assert.deepStrictEqual(resultTwo, [-1]); + }); }); diff --git a/test/test_BloomFilter.js b/test/test_BloomFilter.js index 1db9e3e..a425e42 100644 --- a/test/test_BloomFilter.js +++ b/test/test_BloomFilter.js @@ -1,30 +1,29 @@ const assert = require('assert'); -const BloomFilter = require('../src').BloomFilter; +const { BloomFilter } = require('../src'); describe("Bloom Filter", () => { + const myBloomFilter = new BloomFilter(100, 25); + const t1 = "Genshin Impact"; const t2 = "Dead Cells"; const t3 = "Katana Zero"; const + t4 = "Paladins"; - const myBloomFilter = new BloomFilter(100,25); - const t1="Genshin Impact", t2="Dead Cells", t3="Katana Zero", t4="Paladins"; - - it("Insert a few values",() =>{ - assert.doesNotThrow(() => { - myBloomFilter.insert(t1); - myBloomFilter.insert(t2); - }); + it("Insert a few values", () => { + assert.doesNotThrow(() => { + myBloomFilter.insert(t1); + myBloomFilter.insert(t2); }); + }); - it("check for existence of an inserted value", () => { - assert.strictEqual(myBloomFilter.exists(t1),1); - assert.strictEqual(myBloomFilter.exists(t2),1); - }); + it("check for existence of an inserted value", () => { + assert.strictEqual(myBloomFilter.exists(t1), 1); + assert.strictEqual(myBloomFilter.exists(t2), 1); + }); - it("Uninserted value should not exist (AKA True Negative)", () => { - assert.strictEqual(myBloomFilter.exists(t3),0); - assert.strictEqual(myBloomFilter.exists(t4),0); - }); + it("Uninserted value should not exist (AKA True Negative)", () => { + assert.strictEqual(myBloomFilter.exists(t3), 0); + assert.strictEqual(myBloomFilter.exists(t4), 0); + }); - it("Should have a low FPR rate (less that 10% clash)",() =>{ - assert.notStrictEqual(myBloomFilter.FalsePositiveRate > 0.1,true) - }); - + it("Should have a low FPR rate (less that 10% clash)", () => { + assert.notStrictEqual(myBloomFilter.FalsePositiveRate > 0.1, true); + }); }); diff --git a/test/test_Trie.js b/test/test_Trie.js index 29c04b7..9f6cf60 100644 --- a/test/test_Trie.js +++ b/test/test_Trie.js @@ -1,35 +1,33 @@ const assert = require('assert'); -const Trie = require('../src').Trie; +const { Trie } = require('../src'); -describe("Trie based tests",() =>{ +describe("Trie based tests", () => { + const myT = new Trie(); + const st1 = "can"; + const st2 = "candy"; + const st3 = "ban"; + const na1 = "batman"; + const searchSpace = "can the real candy ban?"; + const resultPos = [[0, 2], [13, 15], [13, 17], [19, 21]]; + const existResult = [true, true, true, false]; + it("should insert a bunch of keys", () => { + myT.insertList([st1, st2, st3]); + assert.deepStrictEqual(myT.listAllElements(), [st1, st2, st3]); + }); - const myT = new Trie(); - const st1 = "can" - const st2 = "candy" - const st3 = "ban" - const na1 = "batman" - const searchSpace = "can the real candy ban?" - const resultPos = [ [ 0, 2 ], [ 13, 15 ], [ 13, 17 ], [ 19, 21 ] ] - const existResult = [true,true,true,false]; - it("should insert a bunch of keys",() => { - myT.insertList([st1,st2,st3]) - assert.deepStrictEqual(myT.listAllElements(),[st1,st2,st3]) - }); + it("should find correct locations of searchSpace", () => { + const res = myT.find(searchSpace); + assert.deepStrictEqual(res, resultPos); + }); - it("should find correct locations of searchSpace",() => { - const res = myT.find(searchSpace) - assert.deepStrictEqual(res,resultPos) - }); - - it("remove given keys", () => { - myT.removeList([st2,st3]) - assert.deepStrictEqual(myT.listAllElements(),[st1]); - myT.insertList([st2,st3]) - }) - - it("should check whether the given keys exist or not",() => { - const res = myT.containsList([st1,st2,st3,na1]) - assert.deepStrictEqual(res,existResult) - }) -}) + it("remove given keys", () => { + myT.removeList([st2, st3]); + assert.deepStrictEqual(myT.listAllElements(), [st1]); + myT.insertList([st2, st3]); + }); + it("should check whether the given keys exist or not", () => { + const res = myT.containsList([st1, st2, st3, na1]); + assert.deepStrictEqual(res, existResult); + }); +}); diff --git a/test/test_bracketBalance.js b/test/test_bracketBalance.js index 468252e..ad1c019 100644 --- a/test/test_bracketBalance.js +++ b/test/test_bracketBalance.js @@ -1,26 +1,26 @@ -const bracketBalance = require('../src').bracketBalance; const assert = require('assert'); +const { bracketBalance } = require('../src'); -describe("Bracket Balanced",() => { - const searchSpace1 = "[[[]]]]",searchSpace2 = "I am (an) as{s}guardian",searchSpace3 = "the [code] {speaker} of nativity {nirvana] is (here",searchSpace4 = "( what if i get (comfortable" +describe("Bracket Balanced", () => { + const searchSpace1 = "[[[]]]]"; const searchSpace2 = "I am (an) as{s}guardian"; const searchSpace3 = "the [code] {speaker} of nativity {nirvana] is (here"; const searchSpace4 = "( what if i get (comfortable"; - it("Returns false due to extra closing bracket", () => { - assert.strictEqual(bracketBalance(searchSpace1),false); - }); + it("Returns false due to extra closing bracket", () => { + assert.strictEqual(bracketBalance(searchSpace1), false); + }); - it("Returns true due to balance", () => { - assert.strictEqual(bracketBalance(searchSpace2),true); - }); + it("Returns true due to balance", () => { + assert.strictEqual(bracketBalance(searchSpace2), true); + }); - it("Returns false due to misbalance", () => { - assert.strictEqual(bracketBalance(searchSpace3),false); - }); + it("Returns false due to misbalance", () => { + assert.strictEqual(bracketBalance(searchSpace3), false); + }); - it("Returns false due to all opening brackets", () => { - assert.strictEqual(bracketBalance(searchSpace4),false); - }); + it("Returns false due to all opening brackets", () => { + assert.strictEqual(bracketBalance(searchSpace4), false); + }); - it("Returns false due to no search space", () => { - assert.strictEqual(bracketBalance(""),false); - }); + it("Returns false due to no search space", () => { + assert.strictEqual(bracketBalance(""), false); + }); }); diff --git a/test/test_dice_coeff.js b/test/test_dice_coeff.js index 9280515..8c4ea08 100644 --- a/test/test_dice_coeff.js +++ b/test/test_dice_coeff.js @@ -1,38 +1,37 @@ -const diceCoeff = require('../src').diceCoeff const assert = require('assert'); +const { diceCoeff } = require('../src'); describe('Dice Coefficient', () => { const stringOne = 'batman'; const stringTwo = 'cowgirl'; - const stringThree = 'batmen'; + const stringThree = 'batmen'; const n = 2; const over = 100; it('should return 1 for the same string', () => { const result = diceCoeff(stringOne, stringOne, n); - assert.strictEqual(result,1); + assert.strictEqual(result, 1); }); - it('should return -1 if either of the strings is empty', () => { + it('should return -1 if either of the strings is empty', () => { const resultOne = diceCoeff('', stringTwo, n); - assert.strictEqual(resultOne,-1); + assert.strictEqual(resultOne, -1); const resultTwo = diceCoeff(stringOne, '', n); - assert.strictEqual(resultTwo,-1); + assert.strictEqual(resultTwo, -1); }); - it('should return -1 if the n value is more than the minimum length of either of the two strings', () => { + it('should return -1 if the n value is more than the minimum length of either of the two strings', () => { const result = diceCoeff(stringOne, stringTwo, over); assert.strictEqual(result, -1); }); - - it(`should return 0 for ${stringOne} and ${stringTwo} with n = ${n}`, () => { + it(`should return 0 for ${stringOne} and ${stringTwo} with n = ${n}`, () => { const result = diceCoeff(stringOne, stringTwo, n); assert.strictEqual(result, 0); }); - it(`should return 0.6 for ${stringOne} and ${stringThree} with n = ${n}`, () => { + it(`should return 0.6 for ${stringOne} and ${stringThree} with n = ${n}`, () => { const result = diceCoeff(stringOne, stringThree, n); - assert.strictEqual(result, 0.6) + assert.strictEqual(result, 0.6); }); }); diff --git a/test/test_edit_distance.js b/test/test_edit_distance.js index 4ca1187..8d5c962 100644 --- a/test/test_edit_distance.js +++ b/test/test_edit_distance.js @@ -1,26 +1,26 @@ -const editDist = require('../src').editDist; const assert = require('assert'); const editDistance = require('../src').editDist; -describe("Edit Distance Test", ()=> { - const st1 = "bike", st2 = "bichael", st3 = "chef", st4 = "chefery" - it(`should return ${st3.length} for comparision between "" and ${st3}`, () => { - const res = editDistance("",st3); - assert.strictEqual(res,st3.length); - }) +describe("Edit Distance Test", () => { + const st1 = "bike"; const st2 = "bichael"; const st3 = "chef"; const + st4 = "chefery"; + it(`should return ${st3.length} for comparision between "" and ${st3}`, () => { + const res = editDistance("", st3); + assert.strictEqual(res, st3.length); + }); - it(`should return 3 for comparision between ${st3} and ${st4}`, () => { - const res = editDistance(st3,st4); - assert.strictEqual(res,3); - }) - - it(`should return 4 for comparision between ${st1} and ${st3}`, () => { - const res = editDistance(st1,st3); - assert.strictEqual(res,4); - }) - - it(`should return 4 for comparision between ${st1} and ${st2}`, () => { - const res = editDistance(st1,st2); - assert.strictEqual(res,4); - }) -}) \ No newline at end of file + it(`should return 3 for comparision between ${st3} and ${st4}`, () => { + const res = editDistance(st3, st4); + assert.strictEqual(res, 3); + }); + + it(`should return 4 for comparision between ${st1} and ${st3}`, () => { + const res = editDistance(st1, st3); + assert.strictEqual(res, 4); + }); + + it(`should return 4 for comparision between ${st1} and ${st2}`, () => { + const res = editDistance(st1, st2); + assert.strictEqual(res, 4); + }); +}); diff --git a/test/test_lcs.js b/test/test_lcs.js index 5f41b4c..e257782 100644 --- a/test/test_lcs.js +++ b/test/test_lcs.js @@ -1,39 +1,38 @@ -const lcs = require('../src').lcs -const assert = require('assert') +const assert = require('assert'); +const { lcs } = require('../src'); -describe("Tests related to Largest Common SubSequence",() => { +describe("Tests related to Largest Common SubSequence", () => { + const st1 = "bananas"; + const st2 = "panama"; + const st3 = "ppp"; + const st4 = "ananas"; + it(`should return 0 for lcs of ${""} and ${""} -> Handles empty string case`, () => { + const res = lcs("", ""); + assert.strictEqual(res, 0); + }); - const st1 = "bananas" - const st2 = "panama" - const st3 = "ppp" - const st4 = "ananas" - it(`should return 0 for lcs of ${""} and ${""} -> Handles empty string case`, () => { - const res = lcs("","") - assert.strictEqual(res,0); - }) + it(`should return ${st1.length} for lcs of ${st1} and ${st1} -> Handles complete overlap case`, () => { + const res = lcs(st1, st1); + assert.strictEqual(res, st1.length); + }); - it(`should return ${st1.length} for lcs of ${st1} and ${st1} -> Handles complete overlap case`, () => { - const res = lcs(st1,st1) - assert.strictEqual(res,st1.length) - }) - - it(`should return 4 for lcs of ${st1} and ${st2} -> handles partial overlap case`, () => { - const res = lcs(st1,st2) - assert.strictEqual(res,4) - }) + it(`should return 4 for lcs of ${st1} and ${st2} -> handles partial overlap case`, () => { + const res = lcs(st1, st2); + assert.strictEqual(res, 4); + }); - it(`should return 0 for lcs of ${st1} and ${st3} -> handles no overlap case`, () => { - const res = lcs(st1,st3) - assert.strictEqual(res,0) - }) + it(`should return 0 for lcs of ${st1} and ${st3} -> handles no overlap case`, () => { + const res = lcs(st1, st3); + assert.strictEqual(res, 0); + }); - it(`should return 6 for lcs of ${st1} and ${st4} -> handles partial overlap case`, () => { - const res = lcs(st1,st4) - assert.strictEqual(res,6) - }) + it(`should return 6 for lcs of ${st1} and ${st4} -> handles partial overlap case`, () => { + const res = lcs(st1, st4); + assert.strictEqual(res, 6); + }); - it(`should return 1 for lcs of ${st2} and ${st3} -> handles repetative letter case`, () => { - const res = lcs(st2,st3) - assert.strictEqual(res,1) - }) -}) \ No newline at end of file + it(`should return 1 for lcs of ${st2} and ${st3} -> handles repetative letter case`, () => { + const res = lcs(st2, st3); + assert.strictEqual(res, 1); + }); +}); diff --git a/test/test_sort.js b/test/test_sort.js index 87d0a23..e75f7ff 100644 --- a/test/test_sort.js +++ b/test/test_sort.js @@ -1,49 +1,48 @@ -const sort = require('../src').customSort.sort; -const sorted = require('../src').customSort.sorted; const assert = require('assert'); - -describe("Custom String Sorting",() => { - - const unsortedArr = ["its","the","its","the","rick","dance"]; - const reverseComparator = (y,x) =>{ - let i=0; - while(i { - const res = sort(unsortedArr,true); - assert.deepStrictEqual(res,[ 5, 0, 2, 4, 1, 3 ]); - }); - - it(`should return correct sorted order for the array ${unsortedArr}`,() => { - const res = sort(unsortedArr,false); - assert.deepStrictEqual(res,[ 'dance', 'its', 'its', 'rick', 'the', 'the' ]); - }) - - it(`should return correct descending sort for the array ${unsortedArr}`,() => { - const res = sort(unsortedArr,false,reverseComparator); - assert.deepStrictEqual(res,[ 'the', 'the', 'rick', 'its', 'its', 'dance' ]); - }) - - it(`should return [] for empty array`,() => { - const res = sort([],false); - assert.deepStrictEqual(res,[]); - }) - - it(`should return false for unsorted array`, () =>{ - const res = sorted(unsortedArr); - assert.deepStrictEqual(res,false); - }); - - it(`should return true for sorted array`, () =>{ - const res = sorted(sort(unsortedArr,false)); - assert.deepStrictEqual(res,true); - }); +const { sort } = require('../src').customSort; +const { sorted } = require('../src').customSort; + + +describe("Custom String Sorting", () => { + const unsortedArr = ["its", "the", "its", "the", "rick", "dance"]; + const reverseComparator = (y, x) => { + let i = 0; + while (i < x.length && i < y.length) { + if (x.charCodeAt(i) != y.charCodeAt(i)) { + return (x.charCodeAt(i) - y.charCodeAt(i)); + } + i++; + } + return (x.length - y.length); + }; + + it(`should return correct indices for the array ${unsortedArr}`, () => { + const res = sort(unsortedArr, true); + assert.deepStrictEqual(res, [5, 0, 2, 4, 1, 3]); + }); + + it(`should return correct sorted order for the array ${unsortedArr}`, () => { + const res = sort(unsortedArr, false); + assert.deepStrictEqual(res, ['dance', 'its', 'its', 'rick', 'the', 'the']); + }); + + it(`should return correct descending sort for the array ${unsortedArr}`, () => { + const res = sort(unsortedArr, false, reverseComparator); + assert.deepStrictEqual(res, ['the', 'the', 'rick', 'its', 'its', 'dance']); + }); + + it(`should return [] for empty array`, () => { + const res = sort([], false); + assert.deepStrictEqual(res, []); + }); + + it(`should return false for unsorted array`, () => { + const res = sorted(unsortedArr); + assert.deepStrictEqual(res, false); + }); + + it(`should return true for sorted array`, () => { + const res = sorted(sort(unsortedArr, false)); + assert.deepStrictEqual(res, true); + }); });