It is less efficient to use (s1,s2).zipped
than (s1 zip s2)
, since you do not need to create tuples; instead, you create functions that take two arguments.
Even better for efficiency, but not ease of use, is to define your own custom folder with a chain:
abstract class StrFold[@specialized T](var result: T) { def apply(c1: Char, c2: Char): Unit def done: Boolean } def strfold[@specialized T](s1: String, s2: String)(folder: StrFold[T]): T = { var i = 0 val L = math.min(s1.length, s2.length) while (i < L) { folder(s1.charAt(i), s2.charAt(i)) if (folder.done) return folder.result i += 1 } folder.result }
Now, if you want to find the length of the longest common prefix, you
class LcpFind extends StrFold(0) { var done = false def apply(c1: Char, c2: Char) { if (c1 == c2) result += 1 else done = true } } def lcp(s1: String, s2: String) = strfold(s1,s2)(new LcpFind)
This is a fair job β perhaps almost the same as just writing an imperative or recursive function code to compute LCP without a fold-with-escape clause.
But it should be almost as fast as writing down material every time. (The only penalty should be to create a (tiny) LcpFind
object every time, and if you really wanted to be able to reuse it by resetting result
to zero between calls or you could change StrFold
and StrFold
to implement and call the reset
method by changing the input a parameter called zero
and having a separate result
method.)
source share