|
| 1 | +// The string separator that is being used for "word" and "text" concatenation. |
| 2 | +const SEPARATOR = '$'; |
| 3 | + |
1 | 4 | /**
|
2 |
| - * @param {string} word |
3 |
| - * @param {string} text |
| 5 | + * @param {string} zString |
4 | 6 | * @return {number[]}
|
5 | 7 | */
|
6 |
| - |
7 |
| -function buildZArray(word, text) { |
8 |
| - const zString = `${word}$${text}`; |
| 8 | +function buildZArray(zString) { |
9 | 9 | const zArray = new Array(zString.length);
|
| 10 | + |
10 | 11 | let left = 0;
|
11 | 12 | let right = 0;
|
12 | 13 | let k = 0;
|
@@ -44,14 +45,32 @@ function buildZArray(word, text) {
|
44 | 45 | /**
|
45 | 46 | * @param {string} text
|
46 | 47 | * @param {string} word
|
47 |
| - * @return {number} |
| 48 | + * @return {number[]} |
48 | 49 | */
|
49 | 50 | export default function zAlgorithm(text, word) {
|
50 |
| - const zArray = buildZArray(word, text); |
51 |
| - for (let i = 1; i < zArray.length; i += 1) { |
52 |
| - if (zArray[i] === word.length) { |
53 |
| - return (i - word.length - 1); |
| 51 | + // The list of word's positions in text. Word may be found in the same text |
| 52 | + // in several different positions. Thus it is an array. |
| 53 | + const wordPositions = []; |
| 54 | + |
| 55 | + // Concatenate word and string. Word will be a prefix to a string. |
| 56 | + const zString = `${word}${SEPARATOR}${text}`; |
| 57 | + |
| 58 | + // Generate Z-array for concatenated string. |
| 59 | + const zArray = buildZArray(zString); |
| 60 | + |
| 61 | + // Based on Z-array properties each cell will tell us the length of the match between |
| 62 | + // the string prefix and current sub-text. Thus we're may find all positions in zArray |
| 63 | + // with the number that equals to the length of the word (zString prefix) and based on |
| 64 | + // that positions we'll be able to calculate word positions in text. |
| 65 | + for (let charIndex = 1; charIndex < zArray.length; charIndex += 1) { |
| 66 | + if (zArray[charIndex] === word.length) { |
| 67 | + // Since we did concatenation to form zString we need to subtract prefix |
| 68 | + // and separator lengths. |
| 69 | + const wordPosition = charIndex - word.length - SEPARATOR.length; |
| 70 | + wordPositions.push(wordPosition); |
54 | 71 | }
|
55 | 72 | }
|
56 |
| - return -1; |
| 73 | + |
| 74 | + // Return the list of word positions. |
| 75 | + return wordPositions; |
57 | 76 | }
|
0 commit comments