From 5066d546a94de767fead12ca92221c1df1745f67 Mon Sep 17 00:00:00 2001 From: Adrito-M Date: Sat, 29 Oct 2022 04:32:32 +0530 Subject: [PATCH 1/4] algorithm: ZFunction --- String/ZFunction.js | 32 ++++++++++++++++++++++++++++++++ String/test/ZFunction.test.js | 15 +++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 String/ZFunction.js create mode 100644 String/test/ZFunction.test.js diff --git a/String/ZFunction.js b/String/ZFunction.js new file mode 100644 index 0000000000..ed38ce7ae1 --- /dev/null +++ b/String/ZFunction.js @@ -0,0 +1,32 @@ +/** + * Author: Adrito Mukherjee + * Implementation of ZFunction in JavaScript + * ZFunction at an index i gives the length of the longest substring starting at i, that is also a prefix of the whole string + * ZFunction for all indices in a string can be calculated in O(N) + * Explanation: https://cp-algorithms.com/string/z-function.html + */ + +function ZFunction (text) { + const length = text.length + const ZArray = Array(length).fill(0) + let left = 0 + let right = 0 + for (let index = 0; index < length; index++) { + if (index <= right) { + ZArray[index] = Math.min(right - index + 1, ZArray[index - left]) + } + while ( + index + ZArray[index] < length && + text[ZArray[index]] === text[index + ZArray[index]] + ) { + ZArray[index]++ + } + if (index + ZArray[index] - 1 > right) { + left = index + right = index + ZArray[index] - 1 + } + } + return ZArray +} + +export default ZFunction diff --git a/String/test/ZFunction.test.js b/String/test/ZFunction.test.js new file mode 100644 index 0000000000..405848f855 --- /dev/null +++ b/String/test/ZFunction.test.js @@ -0,0 +1,15 @@ +import ZFunction from '../ZFunction' + +test('Test Case 1', () => { + const text = 'aabxaayaab' + const ZArray = ZFunction(text) + expect(ZArray).toEqual([10, 1, 0, 0, 2, 1, 0, 3, 1, 0]) +}) + +test('Test Case 2', () => { + const text = 'aabxaabxcaabxaabxay' + const ZArray = ZFunction(text) + expect(ZArray).toEqual([ + 19, 1, 0, 0, 4, 1, 0, 0, 0, 8, 1, 0, 0, 5, 1, 0, 0, 1, 0 + ]) +}) From f85505182b1bc97705e5655545ef446e103a25c5 Mon Sep 17 00:00:00 2001 From: Adrito-M Date: Sun, 30 Oct 2022 01:30:20 +0530 Subject: [PATCH 2/4] made requested changes --- String/ZFunction.js | 31 ++++++++++++++++++++----------- String/test/ZFunction.test.js | 21 ++++++++------------- 2 files changed, 28 insertions(+), 24 deletions(-) diff --git a/String/ZFunction.js b/String/ZFunction.js index ed38ce7ae1..2498f0fc80 100644 --- a/String/ZFunction.js +++ b/String/ZFunction.js @@ -1,32 +1,41 @@ /** - * Author: Adrito Mukherjee + * @author: Adrito Mukherjee * Implementation of ZFunction in JavaScript * ZFunction at an index i gives the length of the longest substring starting at i, that is also a prefix of the whole string * ZFunction for all indices in a string can be calculated in O(N) * Explanation: https://cp-algorithms.com/string/z-function.html + * @param {String} text The string whose Z Function is to be calculated + * @return {Array} Returns an array whose i-th index is the value of Z Function for text at index i */ -function ZFunction (text) { +function zFunction (text) { const length = text.length - const ZArray = Array(length).fill(0) + const zArray = Array(length).fill(0) + // Initializing left and right variable to zero let left = 0 let right = 0 for (let index = 0; index < length; index++) { + // If index is less than or equal to right, we reuse the values of zFunction at index right-index+1 + // It is made sure that value of zFunction at index is not greater than maximum possible value at index if (index <= right) { - ZArray[index] = Math.min(right - index + 1, ZArray[index - left]) + zArray[index] = Math.min(right - index + 1, zArray[index - left]) } + + // After zArray[index] is initialized, we see if we can increase its value by trivially comparing charcter by character while ( - index + ZArray[index] < length && - text[ZArray[index]] === text[index + ZArray[index]] + index + zArray[index] < length && + text[zArray[index]] === text[index + zArray[index]] ) { - ZArray[index]++ + zArray[index]++ } - if (index + ZArray[index] - 1 > right) { + + // If index + zArray[index] - 1 is greater than right, we update values of variables left and right + if (index + zArray[index] - 1 > right) { left = index - right = index + ZArray[index] - 1 + right = index + zArray[index] - 1 } } - return ZArray + return zArray } -export default ZFunction +export default zFunction diff --git a/String/test/ZFunction.test.js b/String/test/ZFunction.test.js index 405848f855..5ff3036086 100644 --- a/String/test/ZFunction.test.js +++ b/String/test/ZFunction.test.js @@ -1,15 +1,10 @@ -import ZFunction from '../ZFunction' +import zFunction from '../ZFunction' -test('Test Case 1', () => { - const text = 'aabxaayaab' - const ZArray = ZFunction(text) - expect(ZArray).toEqual([10, 1, 0, 0, 2, 1, 0, 3, 1, 0]) -}) - -test('Test Case 2', () => { - const text = 'aabxaabxcaabxaabxay' - const ZArray = ZFunction(text) - expect(ZArray).toEqual([ - 19, 1, 0, 0, 4, 1, 0, 0, 0, 8, 1, 0, 0, 5, 1, 0, 0, 1, 0 - ]) +describe('Testing the zFunction', () => { + it('Check the zFunction of a string', () => { + expect(zFunction('aabxaayaab')).toEqual([10, 1, 0, 0, 2, 1, 0, 3, 1, 0]) + expect(zFunction('aabxaabxcaabxaabxay')).toEqual([ + 19, 1, 0, 0, 4, 1, 0, 0, 0, 8, 1, 0, 0, 5, 1, 0, 0, 1, 0 + ]) + }) }) From 64c91101d7355285af0dcfc930e5045fb6f30136 Mon Sep 17 00:00:00 2001 From: Adrito-M Date: Sun, 30 Oct 2022 01:32:11 +0530 Subject: [PATCH 3/4] corrected spelling mistakes --- String/ZFunction.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/String/ZFunction.js b/String/ZFunction.js index 2498f0fc80..07060d0ac6 100644 --- a/String/ZFunction.js +++ b/String/ZFunction.js @@ -21,7 +21,7 @@ function zFunction (text) { zArray[index] = Math.min(right - index + 1, zArray[index - left]) } - // After zArray[index] is initialized, we see if we can increase its value by trivially comparing charcter by character + // After zArray[index] is initialized, we see if we can increase its value by trivially comparing character by character while ( index + zArray[index] < length && text[zArray[index]] === text[index + zArray[index]] From f001e8cfb75533690ec36a385c8631d31d30170d Mon Sep 17 00:00:00 2001 From: Adrito-M Date: Sun, 30 Oct 2022 21:45:16 +0530 Subject: [PATCH 4/4] made requested changes --- String/ZFunction.js | 2 +- String/test/ZFunction.test.js | 12 +++++------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/String/ZFunction.js b/String/ZFunction.js index 07060d0ac6..0d1ff2b127 100644 --- a/String/ZFunction.js +++ b/String/ZFunction.js @@ -3,7 +3,7 @@ * Implementation of ZFunction in JavaScript * ZFunction at an index i gives the length of the longest substring starting at i, that is also a prefix of the whole string * ZFunction for all indices in a string can be calculated in O(N) - * Explanation: https://cp-algorithms.com/string/z-function.html + * @see https://cp-algorithms.com/string/z-function.html * @param {String} text The string whose Z Function is to be calculated * @return {Array} Returns an array whose i-th index is the value of Z Function for text at index i */ diff --git a/String/test/ZFunction.test.js b/String/test/ZFunction.test.js index 5ff3036086..a945f2804f 100644 --- a/String/test/ZFunction.test.js +++ b/String/test/ZFunction.test.js @@ -1,10 +1,8 @@ import zFunction from '../ZFunction' -describe('Testing the zFunction', () => { - it('Check the zFunction of a string', () => { - expect(zFunction('aabxaayaab')).toEqual([10, 1, 0, 0, 2, 1, 0, 3, 1, 0]) - expect(zFunction('aabxaabxcaabxaabxay')).toEqual([ - 19, 1, 0, 0, 4, 1, 0, 0, 0, 8, 1, 0, 0, 5, 1, 0, 0, 1, 0 - ]) - }) +test('Testing zFunction', () => { + expect(zFunction('aabxaayaab')).toEqual([10, 1, 0, 0, 2, 1, 0, 3, 1, 0]) + expect(zFunction('aabxaabxcaabxaabxay')).toEqual([ + 19, 1, 0, 0, 4, 1, 0, 0, 0, 8, 1, 0, 0, 5, 1, 0, 0, 1, 0 + ]) })