2017-04-10 9 views
1

与えられた文字列がスカラを使って他の文字列の部分文字列である回数を見つけるためのエレガントな方法は何ですか? 与えられた文字列がスカラを使って他の文字列の部分文字列であることを見つける

明確にする必要があります下にテストケース

要件は何ですか:

ここ
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) 
    } 

} 

私はそこには、必要があるとし再帰とマッチ/ case節の代わりにScalaの高次関数を利用する、クリーンな1つのライナーであること。

+2

うーん...私は1つのライナーを見つけることの誘惑から離れatayすることをアドバイスします。最初に、あなたのソリューションの「時間複雑さ」に焦点を当ててみてください。それを世話した後でさえ、あなたは1ライナーかエレガンスを探してください。部分文字列(実際にはO(n))の 'n '時間の使用を避けるソリューションを考えると、あなたのソリューションはパフォーマンスが非常に悪くなります。 –

+0

同様に '.tail'はStringもO(n)であり、避けるべきです。 –

+0

良い点、私は何とかそれを逃した。 – GA1

答えて

3

中のキーワードの出現箇所の数を返します。 slidingを使用してスライディングウインドウのイテレータを作成し、ターゲットのStringと等しいウインドウを数えます。

この解決策は機能している間も、許容できるパフォーマンスを提供します。

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

素晴らしいですね。このソリューションの時間の複雑さはどのくらいですか? – GA1

+0

さて、あなたの 'src'の長さは' m'で、 'tgt'の長さは' n'です。次に、ウィンドウイテレータを作成するステップ1は 'O(m)'です。このイテレーターは 'm-n'ウィンドウストリングを持ちます。ステップ2 - カウントは、全てのウィンドウストリングに対して、長さ「n」のウィンドウストリングと「tgt」ストリングとの比較を含む。それは 'O(n * m)'です。ですから、すべての複雑さは「O(m * n)」です –

+0

これはまさに私が探していたソリューションです。私はまだ不思議です。あなたの表記法に従うと、 'O(n)'に同じこと(必ずしも一つのライナーではない)を達成するアルゴリズムがありますか?これは、 'src'の長さが' O'の言葉では無関係なアルゴリズムです。 – GA1

0

おそらく、このJavaの機能を使用することができます。

StringUtils.countMatches(stringToFindMatchesIn, keyWordToFind); 

これは慣用的なScalaの解決策を探しているなら、あなたが使用できる文字列

+0

OPがそれを使うことは許されないと思います。これは宿題の質問/運動のように見えます。 –

関連する問題