String 使用scala查找给定字符串作为另一个字符串的子字符串的次数
使用scala查找给定字符串是另一个字符串的子字符串的次数的优雅方法是什么 以下测试用例应明确哪些是要求:String 使用scala查找给定字符串作为另一个字符串的子字符串的次数,string,scala,find-occurrences,String,Scala,Find Occurrences,使用scala查找给定字符串是另一个字符串的子字符串的次数的优雅方法是什么 以下测试用例应明确哪些是要求: import org.scalatest.FunSuite class WordOccurrencesSolverTest extends FunSuite { private val solver = new WordOccurrencesSolver() test("solve for a in a") { assert(solver.solve("a", "a"
import org.scalatest.FunSuite
class WordOccurrencesSolverTest extends FunSuite {
private val solver = new WordOccurrencesSolver()
test("solve for a in a") {
assert(solver.solve("a", "a") === 1)
}
test("solve for b in a") {
assert(solver.solve("b", "a") === 0)
}
test("solve for a in aa") {
assert(solver.solve("a", "aa") === 2)
}
test("solve for b in ab") {
assert(solver.solve("b", "ab") === 1)
}
test("solve for ab in ab") {
assert(solver.solve("ab", "ab") === 1)
}
test("solve for ab in abab") {
assert(solver.solve("ab", "abab") === 2)
}
test("solve for aa in aaa") {
assert(solver.solve("aa", "aaa") === 2)
}
}
以下是我对这个问题的解决方案,对此我并不感到特别自豪:
class WordOccurrencesSolver {
def solve(word: String, text: String): Int = {
val n = word.length
def solve(acc: Int, word: String, sb: String): Int = sb match {
case _ if sb.length < n => acc
case _ if sb.substring(0, n) == word => solve(acc + 1, word, sb.tail)
case _ => solve(acc, word, sb.tail)
}
solve(0, word, text)
}
}
class WordOccurrencesSolver{
def solve(字:字符串,文本:字符串):Int={
val n=字长
def solve(acc:Int,word:String,sb:String):Int=sb匹配{
案例uu如果sb.lengthacc
大小写uu如果sb.子串(0,n)=word=>solve(acc+1,word,sb.tail)
大小写=>解决(acc、word、sb.tail)
}
求解(0,单词,文本)
}
}
我假设必须有一个干净的一行程序,它利用Scala的高阶函数,而不是递归和match/case子句。您可能可以使用以下java函数:
StringUtils.countMatches(stringToFindMatchesIn, keyWordToFind );
这将返回字符串中关键字出现的次数如果您正在寻找惯用的Scala解决方案,则可以使用滑动创建滑动窗口迭代器,并计算与目标字符串相等的wondows 此解决方案在发挥功能的同时,也为您提供了可接受的性能
def countOccurrences(src: String, tgt: String): Int =
src.sliding(tgt.length).count(window => window == tgt)
好。。。我会建议你远离寻找一句俏皮话的诱惑。首先,试着关注解决方案的时间复杂性。只有在注意到这一点后,你才应该寻找一个衬里或优雅。试着想出一个解决方案,避免子字符串的
n
时间使用(实际上是O(n))使您的解决方案在性能上非常差。类似地。字符串的尾部也是O(n),应该避免。好的一点,我不知何故错过了它。我认为OP不允许使用它。这看起来像是一个家庭作业问题/练习。StringUtils来自Apache Commons,而不是核心Java库!无论如何,这不是Scala唯一的方法。@ViacheslavRodionov这是Scala的工作,它似乎是正确的(做需要的事情)。而且它可能比答案更有效upper@MikhailIonkin请再次阅读原始问题以及我上面的评论。仅凭这一点还不足以提出这段代码作为解决方案。@ViacheslavRodionov在谷歌我发现了这个问题,这个答案对我很有帮助。这是一款优雅、经过测试(生产质量)的“一线”解决方案。是的,关于clear Scala解决方案的问题到此结束,但我不确定它是否对所有人都是最好的。看起来很棒。这个解决方案的时间复杂度是多少?嗯。。。假设您的src
长度m
,tgt
长度n
。然后第1步-创建窗口迭代器是O(m)
。此迭代器将具有m-n
窗口字符串。步骤2-计数涉及将长度为n
的窗口字符串与每个窗口字符串的tgt
字符串进行比较。所以它是O(n*m)
。因此,总体的复杂性是O(m*n)
很好,这正是我想要找到的解决方案。不过我还是很好奇。在O(n)
中是否有算法可以按照您的符号实现相同的事情(不一定是一行程序)?这是一种与src
的长度无关的算法,用O
术语来说。子串搜索是一个非常活跃的领域,因此有许多出色的算法,其中一些算法取决于条件,而有些则普遍适用。你可以在这里详细了解他们-。但请注意,这篇文章是以数学为中心的。但你可以在谷歌上搜索这些算法的简单解释,但不会有任何O(n)算法,因为这是不可能的。即使是O(m)算法也应该是不可能的。