【问题标题】: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 可能会提高效率。
【解决方案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尽管它是可变的,因为我没有找到另一种方法来以相反的顺序遍历字符串。你会如何建议修复/改进它?