Skip to content

Instantly share code, notes, and snippets.

@danielfm
Last active August 29, 2015 14:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save danielfm/8f458fe8ee0530f284cc to your computer and use it in GitHub Desktop.
Save danielfm/8f458fe8ee0530f284cc to your computer and use it in GitHub Desktop.
Boyer-Moore-Horspool implementation for rope.plt
#lang racket
(require (planet "rope.ss" ("dyoo" "rope.plt" 3)))
;; Boyer-Moore-Horspool algorithm for rope.plt
;; http://en.wikipedia.org/wiki/Boyer-Moore-Horspool_algorithm
;; http://planet.racket-lang.org/display.ss?package=rope.plt&owner=dyoo
(define (build-skip-table subrope)
(let ([sublen (rope-length subrope)]
[bcs (make-weak-hash)]
[scan 0])
(rope-for-each
(lambda (ch)
(when (< scan (sub1 sublen))
(hash-set! bcs ch (sub1 (- sublen scan)))
(set! scan (add1 scan))))
subrope)
bcs))
(define (rope-index-of rope subrope i)
(let ([len (rope-length rope)]
[sublen (rope-length subrope)]
[bcs (build-skip-table subrope)]
[idx -1])
(do ([j (sub1 (+ i sublen)) (+ j (hash-ref bcs (rope-ref rope j) sublen))])
((or (>= idx 0) (>= j len)) idx)
(do ([x j (sub1 x)]
[y (sub1 sublen) (sub1 y)])
((or (eq? y -1) (not (eq? (rope-ref rope x) (rope-ref subrope y)))) idx)
(when (zero? y)
(set! idx x))))))
(module+ test
(require rackunit)
(define a-rope (string->rope "The Boyer-Moore-Horspool algorithm is an algorithm för finding substrings in strings"))
(check-equal? 51 (rope-index-of a-rope (string->rope "för") 0))
(check-equal? 25 (rope-index-of a-rope (string->rope "algorithm") 0))
(check-equal? 41 (rope-index-of a-rope (string->rope "algorithm") 26))
(check-equal? -1 (rope-index-of a-rope (string->rope "algorithm") 42))
(check-equal? -1 (rope-index-of a-rope (string->rope "Algorithm") 0)))
(provide rope-index-of)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment