【问题标题】:Longest common suffix最长公共后缀
【发布时间】:2017-03-09 11:29:41
【问题描述】:

我想在 Scala 中找到两个字符串的最长公共后缀。

def longestSuffix(s1: String, s2: String) = {
  val it = (s1.reverseIterator zip s2.reverseIterator) takeWhile {case (x, y) => x == y}
  it.map (_._1).toList.reverse.mkString
}

这段代码很笨拙,而且可能效率低下(例如,因为反转)。如何在功能上找到最长的公共后缀,即没有可变变量?

【问题讨论】:

    标签: string scala functional-programming


    【解决方案1】:

    改进它的一种方法是在最后一次操作中连接反向和映射:

    str1.reverseIterator.zip(str2.reverseIterator).takeWhile( c => c._1 == c._2)
    .toList.reverseMap(c => c._1) mkString ""
    

    先做一个list,然后reverseMap这个list

    【讨论】:

      【解决方案2】:

      我们可以遍历子字符串,没有反向:

      def longestSuffix(s1: String, s2: String) = {
        s1.substring(s1.length to 0 by -1 takeWhile { n => s2.endsWith(s1.substring(n)) } last)
      }
      

      【讨论】:

      • 谢谢。有趣但有点复杂。
      【解决方案3】:

      tails 产生子字符串,然后返回适合的第一个。

      def longestSuffix(s1: String, s2: String) =
        s1.tails.dropWhile(!s2.endsWith(_)).next
      

      对两个输入中较短的一个调用 tails 可能会提高效率。

      【讨论】:

      • 谢谢。看起来不错,但恐怕是O(N^2)
      【解决方案4】:

      我想出了一个这样的解决方案:

      def commonSuffix(s1: String, s2: String): String = {
        val n = (s1.reverseIterator zip s2.reverseIterator) // 可变的!
                  .takeWhile {case (a, b) => a == b}
                  。尺寸
        s1.substring(s1.length - n) // 效率高吗?
      }

      请注意,我使用substring 是为了提高效率(不确定它是否正确)。

      这个解决方案也不是完全“功能性的”,因为我使用的是reverseIterator尽管它是可变的,因为我没有找到另一种方法来以相反的顺序遍历字符串。你会如何建议修复/改进它?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-09-11
        • 2014-10-13
        • 2022-11-22
        • 2021-12-28
        • 2018-09-30
        • 2013-04-14
        • 2012-02-01
        • 2020-07-05
        相关资源
        最近更新 更多