使用scala

时间:2017-04-10 12:45:05

标签: 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") === 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)
  }

}

我认为必须有一个干净的衬里,它利用Scala的高阶函数而不是递归和匹配/ case子句。

2 个答案:

答案 0 :(得分:5)

如果您正在寻找惯用的Scala解决方案,那么您可以使用sliding创建一个滑动窗口迭代器并计算与目标String相等的wondows。

这个解决方案虽然有效,但也为您提供了可接受的性能。

def countOccurrences(src: String, tgt: String): Int =
  src.sliding(tgt.length).count(window => window == tgt)

答案 1 :(得分:-1)

你可以使用这个java函数:

StringUtils.countMatches(stringToFindMatchesIn, keyWordToFind );

这将返回字符串

中关键字的出现次数