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