我想在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
}
此代码笨拙且可能效率低下(例如因为反转)。如何在功能上找到最长的通用后缀 ,即没有可变变量?
答案 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
尽管它是可变的,因为我没有找到另一种方法以相反的顺序迭代字符串。您如何建议修复/改进它?