Boyer-Moore string search: Difference between revisions

Content added Content deleted
m (→‎{{header|Emacs Lisp}}: minor cleanup)
Line 16: Line 16:
;; Compile the pattern to a right most position map
;; Compile the pattern to a right most position map
(defun bm_compile_pattern (pattern)
(defun bm_compile_pattern (pattern)
(let* ((R 256) (patLen (length pattern)) (rightMap (make-vector R -1)))
(let ((patLen (length pattern))
(let ((j -1))
(rightMap (make-vector 256 -1))
(while (progn (setq j (1+ j)) (< j patLen))
(j -1))
(aset rightMap (elt pattern j) j) ) )
(while (> patLen (setq j (1+ j)))
(aset rightMap (elt pattern j) j) )
rightMap
rightMap
)
)
Line 28: Line 29:
"Boyer-Moore string search"
"Boyer-Moore string search"
(let ((startPos 0)
(let ((startPos 0)
(skip 0)
(skip 0)
(result nil)
(result nil)
(rightMap nil)
(rightMap (bm_compile_pattern pattern)))
(result nil))

(setq rightMap (bm_compile_pattern pattern))


;; Continue this loop when no result and not exceed the text length
;; Continue this loop when no result and not exceed the text length
Line 40: Line 38:


(let ((idx (length pattern)) (skip1 nil))
(let ((idx (length pattern)) (skip1 nil))
(while (and (not skip1) (>= (setq idx (1- idx)) 0))
(while (and (not skip1) (>= (setq idx (1- idx)) 0))
;; skip when the character at position idx is different
;; skip when the character at position idx is different
(when (/= (elt pattern idx) (elt text (+ startPos idx)))
(when (/= (elt pattern idx) (elt text (+ startPos idx)))
;; looking up the right most position in pattern
;; looking up the right most position in pattern
(let ((right (aref rightMap (elt text (+ startPos idx)))))
(let ((right (aref rightMap (elt text (+ startPos idx)))))
(if (>= right 0)
(if (>= right 0)
(progn (setq skip1 (- idx right))
(setq skip1 (max 1 (- idx right)))
(when (<= skip1 0) (setq skip1 1)))
(setq skip1 (1+ idx))
)
(progn (setq skip1 (1+ idx)))
)
)
)
)
)
)
(if (or (not skip1) (<= skip1 0))
)
(setq result startPos)
(if (or (not skip1) (<= skip1 0))
(progn (setq result startPos))
(setq skip skip1)
(progn (setq skip skip1)) )
)
)
)
)
)
result
result
)
)
)
)



(let ((pattern "alfalfa")
(let ((pattern "alfalfa")