Skip to content

Commit ae9dfd2

Browse files
update eslint rules for kmp
1 parent f90ad4b commit ae9dfd2

File tree

2 files changed

+94
-94
lines changed

2 files changed

+94
-94
lines changed
+92-92
Original file line numberDiff line numberDiff line change
@@ -1,100 +1,100 @@
11

2+
/* *
3+
* The time complexity of KMP algorithm is O(n) in the worst case
4+
* Example use case: Pattern = AABCAB Text = AAABACABAABCABAABCA
5+
* LPSArray = [ 0, 0, 1, 2, 3, 0 ]
6+
* Found = true, at position 13
7+
* */
8+
9+
// Longest prefix suffix - generate an array of the lps for each pattern array value
10+
const createLPS = (pattern, patternLength) => {
11+
// initialise the current longest prefix suffix length and iterator index values
12+
const lps = [patternLength];
13+
lps[0] = 0;
14+
15+
let length = 0;
16+
let i = 1;
17+
// while there is still pattern to iterate over - calculate the lps for i = 1 to patternLength - 1
18+
while (i < patternLength) {
219
/* *
3-
* The time complexity of KMP algorithm is O(n) in the worst case
4-
* Example use case: Pattern = AABCAB Text = AAABACABAABCABAABCA
5-
* LPSArray = [ 0, 0, 1, 2, 3, 0 ]
6-
* Found = true, at position 13
7-
* */
8-
9-
// Longest prefix suffix - generate an array of the longest previous suffix for each pattern array value
10-
const createLPS = (pattern, patternLength, lps) => {
11-
// initialise the current longest prefix suffix length and iterator index values
12-
lps[0] = 0;
13-
let length = 0;
14-
let i = 1;
15-
// while there is still pattern to iterate over - calculate the lps for i = 1 to patternLength - 1
16-
while (i < patternLength) {
17-
/* *
18-
* if the pattern character at position i matches the pattern character at position length, then increment length, update
19-
* the lps to the incremted length value and iterate to the next index i.
20-
* */
21-
if (pattern.charAt(i) === pattern.charAt(length)) {
22-
length++;
23-
lps[i] = length;
24-
i++;
25-
}
26-
// if a match is not found
27-
else {
28-
// if the length value is not 0, then set the length to be the lps value of index length - 1
29-
if (length !== 0) {
30-
length = lps[length - 1];
31-
}
32-
// else if length is 0, then set the lps at position i to length, i.e. 0 and increment i.
33-
else {
34-
lps[i] = length;
35-
i++;
36-
}
37-
}
38-
}
39-
return lps;
20+
* if the pattern character at position i matches the pattern character at position length,
21+
* then increment length, update
22+
* the lps to the incremted length value and iterate to the next index i.
23+
* */
24+
if (pattern.charAt(i) === pattern.charAt(length)) {
25+
length += 1;
26+
lps[i] = length;
27+
i += 1;
28+
// if not matching
29+
} else if (length !== 0) {
30+
// if the length value is not 0, then set the length to be the lps value of index length - 1
31+
length = lps[length - 1];
32+
} else {
33+
// else if length is 0, then set the lps at position i to length, i.e. 0 and increment i.
34+
lps[i] = length;
35+
i += 1;
4036
}
37+
}
38+
return lps;
39+
};
4140

42-
/* *
43-
* Invoke the Knuth-Morris-Pratt pattern matching algorithm to find a Pattern with a Text - this uses a precomputed prefix-suffix
44-
* array/table to essentially skip chunks of the text that we know will match the pattern.
45-
* This algorithm will return true if the pattern is a subset of the text, else it will return false.
46-
* This algorithm accepts two strings, the pattern and text.
47-
* The time complexity of the KMP algorithm is O(n) in the worst case.
48-
* */
49-
const KMPSearch = (pattern, text) => {
50-
const patternLength = pattern.length; // Often referred to as M
51-
const textLength = text.length; // Often referred to as N
41+
/* *
42+
* Invoke the Knuth-Morris-Pratt pattern matching algorithm to find a Pattern with a Text - this
43+
* uses a precomputed prefix-suffix array/table to essentially skip chunks of the text that we
44+
* know will match the pattern. This algorithm will return true if the pattern is a subset of
45+
* the text, else it will return false.
46+
* This algorithm accepts two strings, the pattern and text.
47+
* The time complexity of the KMP algorithm is O(n) in the worst case.
48+
* */
49+
const KMPSearch = (pattern, text) => {
50+
const patternLength = pattern.length; // Often referred to as M
51+
const textLength = text.length; // Often referred to as N
5252

53-
let lps = [patternLength]; // Longest Pattern Suffix - array containing the lps for all pattern value positions
54-
lps = createLPS(pattern, patternLength, lps); // This is preprocessed - before the text is searched for the pattern.
55-
// console.log({ lpsArray: lps })
53+
// Longest Pattern Suffix - array containing the lps for all pattern value positions
54+
const lps = createLPS(pattern, patternLength); // This is preprocessed.
55+
// console.log({ lpsArray: lps })
5656

57-
let patternIndex = 0; // Referred to as P
58-
let textIndex = 0; // Referred to as T
59-
let found = false;
57+
let patternIndex = 0; // Referred to as P
58+
let textIndex = 0; // Referred to as T
59+
let found = false;
6060

61-
// While there is still text left to iterate over and the pattern has not yet been found
62-
while (textIndex < textLength && found === false) {
63-
// if the pattern character at pattern index P equals the text character at text index T, then increment the text and pattern indexes
64-
if (pattern.charAt(patternIndex) === text.charAt(textIndex)) {
65-
textIndex++;
66-
patternIndex++;
67-
}
68-
/* *
69-
* if the pattern index equals the pattern length then the pattern has been successfully found, as such the pattern is a subset of
70-
* the text the pattern index is set to the longest pattern suffix value (the index is decremented due to being zero indexed).
71-
* */
72-
if (patternIndex === patternLength) {
73-
// console.log(`Pattern found at index ${textIndex-patternIndex}`);
74-
patternIndex = lps[patternIndex - 1];
75-
found = true;
76-
}
77-
/* *
78-
* else if there is still text left to iterate over and the pattern character does not match the text character at their respective
79-
* index positions, then check of the pattern Index is 0, i.e. if it is the first pattern position. If so then jump to the next text
80-
* character, else (this is not the first pattern position), then update the pattern index using the generated longest pattern suffix,
81-
* to skip ahead of matching values. This logic will only be encountered after T number of mismatches.
82-
* */
83-
else if (textIndex < textLength && pattern.charAt(patternIndex) !== text.charAt(textIndex)) {
84-
if (patternIndex === 0)
85-
textIndex = textIndex + 1;
86-
else
87-
patternIndex = lps[patternIndex - 1];
88-
}
89-
}
90-
// Pattern has not been found, return false. Else return true.
91-
if (!found) {
92-
// console.log('The pattern was not found!')
93-
return false
94-
}
95-
return true
96-
};
61+
// While there is still text left to iterate over and the pattern has not yet been found
62+
while (textIndex < textLength && found === false) {
63+
// if the pattern char at index pos P equals the text char at text pos T, then increment indexes
64+
if (pattern.charAt(patternIndex) === text.charAt(textIndex)) {
65+
textIndex += 1;
66+
patternIndex += 1;
67+
}
68+
/* *
69+
* if the pattern index equals the pattern length then the pattern has been successfully
70+
* found, as such the pattern is a subset of the text the pattern index is set to the longest
71+
* pattern suffix value (the index is decremented due to being zero indexed).
72+
* */
73+
if (patternIndex === patternLength) {
74+
// console.log(`Pattern found at index ${textIndex-patternIndex}`);
75+
patternIndex = lps[patternIndex - 1];
76+
found = true;
77+
} else if (textIndex < textLength && pattern.charAt(patternIndex) !== text.charAt(textIndex)) {
78+
/* *
79+
* else if there is still text left to iterate over and the pattern character does not match
80+
* the text characterat their respective index positions, then check of the pattern Index is 0,
81+
* i.e. if it is the first pattern position. If so then jump to the next text character, else
82+
* (this is not the first pattern position), then update the pattern index using the generated
83+
* longest prefix suffix, to skip ahead of matching values. This logic will only be encountered
84+
* after T number of mismatches.
85+
* */
86+
if (patternIndex === 0) textIndex += 1;
87+
else patternIndex = lps[patternIndex - 1];
88+
}
89+
}
90+
// Pattern has not been found, return false. Else return true.
91+
if (!found) {
92+
// console.log('The pattern was not found!')
93+
return false;
94+
}
95+
return true;
96+
};
9797

98-
module.exports = {
99-
KMPSearch
100-
};
98+
module.exports = {
99+
KMPSearch,
100+
};

src/_Classics_/knuth-morris-pratt/knuth-morris-pratt.test.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
const { KMPSearch } = require('.');
22

33
describe('Pattern Matching Classic Algorithm: Knuth-Morris-Pratt', () => {
4-
describe('KMPSearch', () =>{
4+
describe('KMPSearch', () => {
55
it('Should return true when the pattern equals the text', () => {
66
expect(KMPSearch('A', 'A')).toEqual(true);
77
});
@@ -36,4 +36,4 @@ describe('Pattern Matching Classic Algorithm: Knuth-Morris-Pratt', () => {
3636
expect(KMPSearch('AAAAAAAA', 'AAAAAA')).toEqual(false);
3737
});
3838
});
39-
});
39+
});

0 commit comments

Comments
 (0)