String 使用zip查找Scala中两个字符串之间的差异

String 使用zip查找Scala中两个字符串之间的差异,string,scala,String,Scala,这是对我的建议的后续行动 我注意到,如果我操作两个字符串(例如,获取最长的公共前缀,计算两个字符串之间的差异等),我倾向于使用zip(如(s1-zip-s2)…) 它看起来不错,但可能效率低下(与命令式代码相比)。对吗?也许,如果性能确实重要,我应该使用命令式算法 现在我试图找出两个字符串是否不同。你会推荐使用zip来做这件事吗?是的,这会因为两个原因而降低效率 您正在创建一个与较短字符串长度相同的字符对列表。这将比原来的两个字符串发生更多的位置。查找最长公共前缀或检查字符串是否在一个字符中不同

这是对我的建议的后续行动

我注意到,如果我操作两个字符串(例如,获取最长的公共前缀,计算两个字符串之间的差异等),我倾向于使用
zip
(如
(s1-zip-s2)…

它看起来不错,但可能效率低下(与命令式代码相比)。对吗?也许,如果性能确实重要,我应该使用命令式算法


现在我试图找出两个字符串是否不同。你会推荐使用
zip
来做这件事吗?

是的,这会因为两个原因而降低效率

  • 您正在创建一个与较短字符串长度相同的字符对列表。这将比原来的两个字符串发生更多的位置。查找最长公共前缀或检查字符串是否在一个字符中不同的常用方法不需要任何额外内存

  • 在查找LCP时,不一定需要遍历整个字符串。由于
    zip
    确实需要这样做,因此首先压缩它们显然效率较低

  • 但这并不意味着您必须使用命令式算法:一个正常的尾部递归函数算法也可以执行

    它看起来不错,但可能效率低下(与命令式代码相比)

    它复制两个输入,因此它实际上是O(n)空间,而在O(1)内存中查找最长的公共前缀可以是时间。此外,它需要O(n)时间,而O(len(LCP))时间就足够了(尽管在最坏的情况下这是O(n)时间),并且它进行内存分配;那是一个昂贵的手术

    现在我试图找出两个字符串是否在一个字符中完全不同。您是否建议使用
    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)