Skip to content

Commit 79874b2

Browse files
feat: implemented kmpseach algo
1 parent 1bd4097 commit 79874b2

File tree

4 files changed

+564
-0
lines changed

4 files changed

+564
-0
lines changed
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
export function computeLPSSteps(pattern) {
2+
const m = pattern.length;
3+
const lps = Array(m).fill(0);
4+
const steps = [];
5+
let len = 0;
6+
let i = 1;
7+
8+
steps.push({
9+
lps: [...lps],
10+
i: 1,
11+
len: 0,
12+
message: "Initializing LPS table. lps[0] is always 0. Starting from i = 1.",
13+
highlight: { i: 1, len: 0, lps: -1 },
14+
});
15+
16+
while (i < m) {
17+
steps.push({
18+
lps: [...lps],
19+
i: i,
20+
len: len,
21+
message: `Comparing pattern[${i}] ('${pattern[i]}') and pattern[${len}] ('${pattern[len]}').`,
22+
highlight: { i: i, len: len, lps: -1 },
23+
});
24+
25+
if (pattern[i] === pattern[len]) {
26+
len++;
27+
lps[i] = len;
28+
steps.push({
29+
lps: [...lps],
30+
i: i,
31+
len: len,
32+
message: `Match! lps[${i}] = ${len}. Increment i and len.`,
33+
highlight: { i: i, len: len, lps: i, state: 'match' },
34+
});
35+
i++;
36+
} else {
37+
if (len !== 0) {
38+
len = lps[len - 1];
39+
steps.push({
40+
lps: [...lps],
41+
i: i,
42+
len: len,
43+
message: `Mismatch. Falling back: len = lps[${len - 1}] = ${len}.`,
44+
highlight: { i: i, len: len, lps: -1, state: 'mismatch' },
45+
});
46+
} else {
47+
lps[i] = 0;
48+
steps.push({
49+
lps: [...lps],
50+
i: i,
51+
len: len,
52+
message: `Mismatch. No fallback. lps[${i}] = 0. Increment i.`,
53+
highlight: { i: i, len: len, lps: i, state: 'mismatch' },
54+
});
55+
i++;
56+
}
57+
}
58+
}
59+
60+
steps.push({
61+
lps: [...lps],
62+
i: m,
63+
len: len,
64+
message: "LPS table computation complete.",
65+
highlight: { i: m, len: len, lps: -1, state: 'done' },
66+
});
67+
return { steps, lpsTable: lps };
68+
}
69+
70+
export function kmpSearchSteps(text, pattern, lps) {
71+
const n = text.length;
72+
const m = pattern.length;
73+
const steps = [];
74+
const matches = [];
75+
let i = 0;
76+
let j = 0;
77+
78+
steps.push({
79+
i: i,
80+
j: j,
81+
matches: [...matches],
82+
message: "Starting KMP search. i = 0 (text), j = 0 (pattern).",
83+
highlight: { i: 0, j: 0, state: 'idle' }
84+
});
85+
86+
while (i < n) {
87+
if (j === 0) {
88+
steps.push({
89+
i: i,
90+
j: j,
91+
matches: [...matches],
92+
message: `Comparing text[${i}] ('${text[i]}') and pattern[${j}] ('${pattern[j]}').`,
93+
highlight: { i: i, j: j, state: 'compare' }
94+
});
95+
} else {
96+
steps.push({
97+
i: i,
98+
j: j,
99+
matches: [...matches],
100+
message: `Comparing text[${i}] ('${text[i]}') and pattern[${j}] ('${pattern[j]}').`,
101+
highlight: { i: i, j: j, state: 'compare' }
102+
});
103+
}
104+
105+
106+
if (pattern[j] === text[i]) {
107+
i++;
108+
j++;
109+
}
110+
111+
if (j === m) {
112+
const matchIndex = i - j;
113+
matches.push(matchIndex);
114+
steps.push({
115+
i: i,
116+
j: j,
117+
matches: [...matches],
118+
message: `PATTERN FOUND! at index ${matchIndex}.`,
119+
highlight: { i: i, j: j, state: 'match', matchIndex: matchIndex }
120+
});
121+
j = lps[j - 1];
122+
steps.push({
123+
i: i,
124+
j: j,
125+
matches: [...matches],
126+
message: `Jumping pattern pointer using LPS: j = lps[${m - 1}] = ${j}.`,
127+
highlight: { i: i, j: j, state: 'jump' }
128+
});
129+
} else if (i < n && pattern[j] !== text[i]) {
130+
if (j !== 0) {
131+
j = lps[j - 1];
132+
steps.push({
133+
i: i,
134+
j: j,
135+
matches: [...matches],
136+
message: `Mismatch. Jumping pattern pointer using LPS: j = lps[${j - 1}] = ${j}.`,
137+
highlight: { i: i, j: j, state: 'jump' }
138+
});
139+
} else {
140+
i++;
141+
steps.push({
142+
i: i,
143+
j: j,
144+
matches: [...matches],
145+
message: `Mismatch at j=0. Incrementing text pointer i to ${i}.`,
146+
highlight: { i: i, j: j, state: 'mismatch' }
147+
});
148+
}
149+
}
150+
}
151+
152+
steps.push({
153+
i: n,
154+
j: j,
155+
matches: [...matches],
156+
message: `Search complete. ${matches.length} match(es) found.`,
157+
highlight: { i: n, j: j, state: 'done' }
158+
});
159+
160+
return { steps, matches };
161+
}

0 commit comments

Comments
 (0)