I have implemented an algorithm to calculate the longest contiguous common subsequence (not to be confused with longest common subsequence, though not important for
Here are a couple improvements:
Beyond that (and the long type hint on the recur mentioned above), I don't see any obvious ways to improve further.
(defn lcs
[^objects a1 ^objects a2]
(let [a1-len (alength a1)
a2-len (alength a2)
prev (int-array (inc a2-len))
curr (int-array (inc a2-len))]
(loop [i 0 max-len 0 prev prev curr curr]
(if (< i a1-len)
(recur (inc i)
(long (loop [j 0 max-len max-len]
(if (< j a2-len)
(if (= (aget a1 i) (aget a2 j))
(let [match-len (inc (aget prev j))]
(do
(aset curr (inc j) match-len)
(recur (inc j) (max max-len match-len))))
(do
(aset curr (inc j) 0)
(recur (inc j) max-len)))
max-len)))
curr
prev)
max-len))))
#'user/lcs
user> (time (lcs a1 a2))
"Elapsed time: 3862.211 msecs"