String 使用zip查找Scala中两个字符串之间的差异
这是对我的建议的后续行动 我注意到,如果我操作两个字符串(例如,获取最长的公共前缀,计算两个字符串之间的差异等),我倾向于使用String 使用zip查找Scala中两个字符串之间的差异,string,scala,String,Scala,这是对我的建议的后续行动 我注意到,如果我操作两个字符串(例如,获取最长的公共前缀,计算两个字符串之间的差异等),我倾向于使用zip(如(s1-zip-s2)…) 它看起来不错,但可能效率低下(与命令式代码相比)。对吗?也许,如果性能确实重要,我应该使用命令式算法 现在我试图找出两个字符串是否不同。你会推荐使用zip来做这件事吗?是的,这会因为两个原因而降低效率 您正在创建一个与较短字符串长度相同的字符对列表。这将比原来的两个字符串发生更多的位置。查找最长公共前缀或检查字符串是否在一个字符中不同
zip
(如(s1-zip-s2)…
)
它看起来不错,但可能效率低下(与命令式代码相比)。对吗?也许,如果性能确实重要,我应该使用命令式算法
现在我试图找出两个字符串是否不同。你会推荐使用
zip
来做这件事吗?是的,这会因为两个原因而降低效率
zip
确实需要这样做,因此首先压缩它们显然效率较低zip
来执行此操作
这取决于字符串的长度以及性能是否至关重要。对于第一个镜头,使用
zip可能没什么问题。在执行zip
时,您可以使用视图进行惰性评估(因此它将只压缩您拍摄的内容)。使用(s1,s2)。压缩的比(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
}
这是一项相当多的工作——可以说,这几乎等同于编写命令式或递归函数代码来计算LCP,而不需要fold with escape子句
但它应该几乎和每次手写低级字符串一样快。(唯一的惩罚应该是创建(微小的)LcpFind
对象,如果确实需要,可以通过在调用之间将result
重置为零来重用它,或者可以修改StrFold
和StrFold
来实现和调用reset
方法,将输入参数更改为zero
,并使用单独的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)