Несколько эффективнее использовать (s1,s2).zipped
, чем (s1 zip s2)
, поскольку вам не нужно создавать кортежи; вместо этого вы создаете функции, которые принимают два аргумента.
Еще лучше для эффективности, но не для простоты использования - это определение собственной пользовательской специализированной папки строк:
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
}
Теперь, если вы хотите найти длину самого длинного общего префикса, вы
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)
Это довольно трудоемкий труд - возможно, почти такой же, как просто написание императивного или рекурсивного функционального кода для вычисления LCP без предложения сгиба с escape-выражением.
Но это должно быть почти так же быстро, как каждый раз писать низкоуровневые строки. (Единственным штрафом должно быть создание (крошечного) LcpFind
объекта каждый раз, и, если вы действительно этого хотите, вы можете использовать его повторно, сбросив result
на ноль между вызовами, или вы можете изменить StrFold
и strfold
на реализовать и вызвать метод reset
, изменив входной параметр с именем zero
и имея отдельный метод result
.)