私は最近、文字列を処理し、そのすべての部分文字列を見つけて、辞書にあるもののリストを保持する Scala コードを書きました。全体的な文字列内の部分文字列の開始と終了も、後で使用するために保持する必要があるため、これを行う最も簡単な方法は、次のようなネストされた for ループを使用することです。
for (i <- 0 until word.length)
for (j <- i until word.length) {
val sub = word.substring(i, j + 1)
// lookup sub in dictionary here and add new match if found
}
演習として、Haskell で同じことをやってみることにしました。部分文字列のインデックスがなくても十分簡単に思えます。このアプローチのようなものを使用して部分文字列を取得し、再帰関数を呼び出して一致を蓄積することができます。しかし、インデックスも必要な場合は、よりトリッキーに思えます。
「親」文字列内の開始インデックスと終了インデックスとともに、連続する各サブ文字列を含むリストを返す関数をどのように作成しますか?
たとえばtokens "blah"
、[("b",0,0), ("bl",0,1), ("bla",0,2), ...]
アップデート
答えの素晴らしい選択と探索する新しいものがたくさんあります。少しいじった後、私は最初の答えに行きました.Danielの使用を許可するという提案で[0..]
.
data Token = Token String Int Int
continuousSubSeqs = filter (not . null) . concatMap tails . inits
tokenize xs = map (\(s, l) -> Token s (head l) (last l)) $ zip s ind
where s = continuousSubSeqs xs
ind = continuousSubSeqs [0..]
私の限られた Haskell の知識を考えると、これは比較的理解しやすいように思えました。