1 //////////////////////////////////////////////////////////////////////////////
4 // ADLib, Prop and their related set of tools and documentation are in the
5 // public domain. The author(s) of this software reserve no copyrights on
6 // the source code and any code generated using the tools. You are encouraged
7 // to use ADLib and Prop to develop software, in both academic and commercial
8 // settings, and are free to incorporate any part of ADLib and Prop into
11 // Although you are under no obligation to do so, we strongly recommend that
12 // you give away all software developed using our tools.
14 // We also ask that credit be given to us when ADLib and/or Prop are used in
15 // your programs, and that this notice be preserved intact in all the source
18 // This software is still under development and we welcome any suggestions
19 // and help from the users.
23 //////////////////////////////////////////////////////////////////////////////
27 #include <AD/strings/kmp.h>
29 void KMP::compile (register const char * pattern
, int len
)
30 { delete [] skip
; skip
= NULL
;
31 if (len
< 0) len
= strlen(pattern
);
32 if ( (patternLength
= len
) > 0) {
36 // ps[i] = Given a prefix |w| of pattern with length i,
37 // the length of the proper prefix of |w|
38 // that is also a suffix of |w|
40 skip
= new Skip
[patternLength
];
41 register int * ps
= new int [patternLength
];
44 for (i
= 1; i
< patternLength
; i
++) {
45 for (w
= ps
[i
-1]; ; w
= ps
[w
-1] ) {
46 if (pattern
[i
] == pattern
[w
]) { ps
[i
] = w
+ 1; break; }
47 if (w
== 0) { ps
[i
] = 0; break; }
51 for (c
= 0; c
< 256; c
++) skip
[0][c
] = 1;
52 skip
[0][(unsigned char)pattern
[0]] = 0;
55 // skip[i][c] = 0 if pattern[i] == c
56 // skip[i][c] = i + 1 - ps( pattern[0 ... i-1] . c )
58 for (i
= 1; i
< patternLength
; i
++) {
59 for (c
= 0; c
< 256; c
++) {
60 if (c
== pattern
[i
]) skip
[i
][c
] = 0;
61 else { w
= ps
[i
-1]; skip
[i
][c
] = i
- w
+ skip
[w
][c
]; }
69 int KMP::Match(register const char * text
, int textLength
) const
70 { if (textLength
< 0) textLength
= strlen(text
);
71 register int m
, p
; // characters matched and text position
72 register int patLen
= patternLength
;
73 register int limit
= textLength
- patLen
;
74 for (m
= 0, p
= 0; p
<= limit
; ) {
75 if (m
== patLen
) return p
;
76 register int d
= skip
[ m
] [ text
[m
+ p
] ];