Skip to content

Commit 0a5162b

Browse files
author
Raghav Dua
committed
Merge pull request algorithm-visualizer#73 from duaraghav8/master
Knuth Morris Pratt
2 parents c175da7 + c503a35 commit 0a5162b

File tree

5 files changed

+153
-3
lines changed

5 files changed

+153
-3
lines changed

algorithm/category.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@
4040
"string": {
4141
"name": "String",
4242
"list": {
43-
"edit_distance": "Edit Distance"
43+
"edit_distance": "Edit Distance",
44+
"knuth_morris_pratt": "KMP Substring Search"
4445
}
4546
},
4647
"dp": {

algorithm/graph_search/bridges/desc.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
2-
"Bridges": "An edge in an undirected connected graph is a bridge iff removing it disconnects the graph. A naive solution to finding bridges in a graph is to:<br />1.Delete an edge E<br />2.Perform DFS Exploration to check is Graph is connected<br />3.Restore Edge E. E is a bridge only if DFS explore determines that the graph is disconnected without E",
2+
"Bridges": "An edge in an undirected connected graph is a bridge iff removing it disconnects the graph. A naive solution to finding bridges in a graph is to:<br />1.Delete an edge E<br />2.Perform DFS Exploration to check if the Graph is still connected<br />3.Restore Edge E. E is a bridge only if DFS exploration determines that the graph is disconnected without E",
33
"Applications": [
4-
"Find vulnerabilities in Graphs and Electrical Circuits"
4+
"Finding vulnerabilities in Graphs and Electrical Circuits"
55
],
66
"Complexity": {
77
"time": "worst O(|E|.(|V|+|E|))",
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"Knuth-Morris-Pratt": "searches for occurrences of a substring W with length K within a main string S with Length N by employing the observation that when a mismatch occurs, the word itself embodies sufficient information to determine where the next match could begin, thus bypassing re-examination of previously matched characters",
3+
"Applications": [
4+
"Substring Search"
5+
],
6+
"Complexity": {
7+
"time": "worst O(|N|+|K|)",
8+
"space": "worst O(|K|)"
9+
},
10+
"References": [
11+
"<a href='https://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm'>Wikipedia</a>"
12+
],
13+
"files": {
14+
"substring_search": "Efficiently find is A is a substring of B (and A's position(s))"
15+
}
16+
}
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
//Fix JS Negative number modulo Bug
2+
Number.prototype.mod = function (n) {
3+
return ((this%n)+n)%n;
4+
};
5+
6+
function randString (length) {
7+
var result = Math.random ().toString (36);
8+
return result.substring (result.length - length);
9+
}
10+
11+
function tracker (substring) {
12+
var i = 1, j = 0;
13+
14+
logger._print ('Initializing i to 1, j to 0.');
15+
substrTracer._select (j);
16+
while (i < track.length) {
17+
substrTracer._select (i)._wait ();
18+
19+
while ( (substring [i] !== substring [j]) && (j > 0) ) {
20+
logger._print ('j = ' + track [j-1]);
21+
trackTracer._select (j-1)._wait ();
22+
trackTracer._deselect (j-1)._wait ();
23+
24+
substrTracer._deselect (j);
25+
j = track [j-1];
26+
logger._print ('j = ' + j);
27+
substrTracer._select (j);
28+
}
29+
30+
if (substring [i] === substring [j]) {
31+
substrTracer._deselect (j);
32+
track [i] = ++j;
33+
trackTracer._notify (i, track [i])._wait ();
34+
trackTracer._denotify (i)._wait ();
35+
logger._print ('substring [ ' + i + ' ] (' + substring [i] + ') equals substring [ ' + j + ' ] (' + substring [j] + '), track [ ' + i + ' ] updated to: ' + track [i]);
36+
37+
logger._print ('j = ' + j);
38+
substrTracer._select (j);
39+
}
40+
else {
41+
track [i] = 0;
42+
logger._print ('substring [ ' + i + ' ] (' + substring [i] + ') is not equal to substring [ ' + j + ' ] (' + substring [j] + '), setting track [' + i + '] to 0');
43+
trackTracer._select (i)._wait ();
44+
trackTracer._deselect (i)._wait ();
45+
}
46+
47+
substrTracer._deselect (i)._wait ();
48+
i++;
49+
logger._print ('i = ' + i);
50+
}
51+
52+
return track;
53+
}
54+
55+
function kmp (string, substr) {
56+
var positions = [], j = 0, startPos;
57+
58+
logger._print ('Constructing Tracker for substring <b>' + substr + '</b>');
59+
track = tracker (substr);
60+
logger._print ('Tracker for substring constructed: [ ' + String (track) + ' ]');
61+
logger._print ('--------------------------------------------------------------------------');
62+
logger._print ('Running KMP...');
63+
64+
logger._print ('Initializing i = 0, j = 0');
65+
for (var i = 0; i < string.length; i++) {
66+
logger._print ('comparing string [' + i + '] (' + string [i] + ') and substring [' + j + '] (' + substr [j] + ')...');
67+
stringTracer._select (i)._wait ();
68+
stringTracer._select (j)._wait ();
69+
70+
if (string [i] === substr [j]) {
71+
logger._print ('they\'re equal!');
72+
73+
if (j === substr.length-1) {
74+
logger._print ('j (' + j + ') equals length of substring - 1 (' + substr.length + '-1), we\'ve found a new match in the string!');
75+
startPos = i - substr.length + 1;
76+
positions.push (startPos);
77+
78+
logger._print ('Adding start position of the substring (' + startPos + ') to the results.');
79+
stringTracer._select (startPos)._wait ();
80+
}
81+
else {
82+
stringTracer._deselect (j)._wait ();
83+
logger._print ('But j (' + j + ') does not equal length of substring (' + substr.length + ') Incrementing j and moving forward.');
84+
j++;
85+
logger._print ('j = ' + j);
86+
stringTracer._select (j)._wait ();
87+
}
88+
}
89+
else {
90+
var tempJ = j - 1;
91+
logger._print ('they\'re NOT equal');
92+
trackTracer._select (tempJ)._wait ();
93+
stringTracer._deselect (j)._wait ();
94+
95+
j = track [(j-1).mod (substr.length)]; //use modulo to wrap around, i.e., if index = -1, access the LAST element of array (PYTHON-LIKE)
96+
97+
logger._print ('Setting j to ' + j);
98+
stringTracer._select (j)._wait ();
99+
trackTracer._deselect (tempJ)._wait ();
100+
}
101+
102+
stringTracer._deselect (i)._wait ();
103+
}
104+
105+
return positions;
106+
}
107+
108+
var positions = kmp (string, substring);
109+
110+
logger._print ('Substring positions are: ' + (positions.length ? String (positions) : 'NONE'));
111+
for (var i = 0; i < positions.length; i++) {
112+
stringTracer._select (positions [i], positions [i] + substring.length - 1)._wait ();
113+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
function randString (length) {
2+
var result = Math.random ().toString (36);
3+
return result.substring (result.length - length);
4+
}
5+
6+
var string = randString (15), substring = randString (5);
7+
//var string = 'abcxabcdabxabcdabcdabxabcda', substring = 'xabcda';
8+
//var string = 'abcxabcdabxabcdabcdabcyiuhsiuhduiahdubhbuuabcdabcysbhbh', substring = 'abcdabcy';
9+
10+
var track = Array.apply (null, Array (substring.length)).map (Number.prototype.valueOf, 0);
11+
12+
var logger = new LogTracer ();
13+
var trackTracer = new Array1DTracer (),
14+
substrTracer = new Array1DTracer (),
15+
stringTracer = new Array1DTracer ();
16+
17+
18+
trackTracer._setData (track);
19+
substrTracer._setData (substring);
20+
stringTracer._setData (string);

0 commit comments

Comments
 (0)