最长的通用后缀

时间:2017-03-09 11:29:42

标签: string scala functional-programming

我想在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
}

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

4 个答案:

答案 0 :(得分:1)

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

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

首先制作一个列表,然后反向映射这个列表

答案 1 :(得分:1)

我们可以迭代子串,无需反转:

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

答案 2 :(得分:1)

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

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

通过在两个输入中较短的一个上调用tails可以获得一些效率。

答案 3 :(得分:0)

我提出了这样的解决方案:

def commonSuffix(s1: String, s2: String): String = {
  val n = (s1.reverseIterator zip s2.reverseIterator) // mutable !
            .takeWhile {case (a, b) => a == b}
            .size
  s1.substring(s1.length - n) // is it efficient ?
}

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

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