Skip to content

Instantly share code, notes, and snippets.

@quephird
Last active August 29, 2015 14:13
Show Gist options
  • Save quephird/26690bd35c01c33271d5 to your computer and use it in GitHub Desktop.
Save quephird/26690bd35c01c33271d5 to your computer and use it in GitHub Desktop.
A really rough first cut of a string searching function using the so-called BNDM algorithm
(defn bndm [pattern string]
"Searches for the pattern in the string using the BNDM algorithm;
it returns a list of the indices where there is a match."
(let [uniq-letters (set pattern)
indexed-letters (map-indexed vector pattern)
bitmasks (into {}
(for [c uniq-letters]
[c (reduce + (map (fn [[idx c']] (if (= c c') (bit-shift-left 1 idx) 0)) indexed-letters))]))]
(loop [d 0 idx 0 acc []]
(cond
(= idx (dec (count string))) acc
:else
(let [c (get string idx)
bitmask (get bitmasks c 0)
new-d (bit-and (bit-or (bit-shift-left d 1) 1) bitmask)
test-bit (bit-shift-left 1 (dec (count pattern)))]
(if (> (bit-and new-d test-bit) 0)
(recur new-d (inc idx) (conj acc (- idx (dec (count pattern)))))
(recur new-d (inc idx) acc)))))))
(bndm "eee" "yeeeeah")
(bndm "bananas" "there are bananas in this string")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment