Skip to content

Instantly share code, notes, and snippets.

@ryukinix
Created July 13, 2017 16:01
Show Gist options
  • Select an option

  • Save ryukinix/6823eb9219a7f240588cadf41457b521 to your computer and use it in GitHub Desktop.

Select an option

Save ryukinix/6823eb9219a7f240588cadf41457b521 to your computer and use it in GitHub Desktop.
KMP substring problem implementation on Common Lisp
;; kmp-fp: Substring Search @ HackerRank
;; Date: Thu 13 Jul 2017 08:48:40 AM -03
;; Manoel Vilela
;; NOTE: I'm programming in Common Lisp or in LOOP-MACRO?
(defun make-prefix-table (pattern length)
"Get the shift prefix array table to use on KMP
algorithm. This value is used to shift string comparison
on the next evaluation after a mismatch"
(loop with prefix-table = (make-array length :initial-element 0)
and prefix = 0
for i from 1 below length
do (loop while (and (> prefix 0)
(not (eq (aref pattern i)
(aref pattern prefix))))
do (setq prefix (aref prefix-table (1- prefix))))
when (eq (aref pattern i)
(aref pattern prefix))
do (incf prefix)
end
do (setf (aref prefix-table i) prefix)
finally (return prefix-table)))
(defun find-substring (pattern string)
"Using the KMP algorithm, find the position of the pattern in string if exists
Otherwise return nil."
(loop with string-length = (length string)
and pattern-length = (length pattern)
and string-index = 0
and pattern-index = 0
with prefix = (make-prefix-table pattern pattern-length)
while (< string-index string-length)
when (eq (aref string string-index)
(aref pattern pattern-index))
do (progn (incf string-index)
(incf pattern-index))
if (= pattern-index pattern-length)
return (- string-index pattern-index)
else
if (and (< string-index string-length)
(not (eq (aref string string-index)
(aref pattern pattern-index))))
if (/= pattern-index 0)
do (setq pattern-index (aref prefix (1- pattern-index)))
else
do (incf string-index)))
(defun main ()
(loop repeat (read)
for string = (read-line)
for pattern = (read-line)
for found = (find-substring pattern string)
for message = (if found "YES" "NO")
do (format t "~a~%" message)))
(main)
@phoe
Copy link
Copy Markdown

phoe commented Dec 8, 2019

Hey! What is the license of this code snippet? I'm looking for an implementation of KMP algorithm that I can use in Clozure Common Lisp which is licensed under Apache-2.0.

@ryukinix
Copy link
Copy Markdown
Author

ryukinix commented Dec 8, 2019

BSD. You can use freely. It's compatible with Apache license. You can find this same algorithm implementation in this library: https://github.com/ryukinix/leraxandria/blob/master/src/string/kmp-substring-search.lisp

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment